├── testsuite ├── config │ └── default.exp ├── libffi.go │ ├── ffitest.h │ ├── static-chain.h │ ├── closure1.c │ ├── aa-direct.c │ └── go.exp ├── libffi.complex │ ├── ffitest.h │ ├── complex_float.c │ ├── complex_double.c │ ├── complex_defs_double.inc │ ├── complex_longdouble.c │ ├── cls_complex_float.c │ ├── complex_defs_float.inc │ ├── cls_complex_double.c │ ├── complex_defs_longdouble.inc │ ├── return_complex1_double.c │ ├── return_complex1_float.c │ ├── return_complex2_double.c │ ├── return_complex2_float.c │ ├── return_complex_double.c │ ├── return_complex_float.c │ ├── cls_complex_longdouble.c │ ├── return_complex1_longdouble.c │ ├── return_complex2_longdouble.c │ ├── return_complex_longdouble.c │ ├── many_complex_double.c │ ├── many_complex_float.c │ ├── many_complex_longdouble.c │ ├── cls_align_complex_double.c │ ├── cls_align_complex_float.c │ ├── cls_complex_struct_double.c │ ├── cls_complex_struct_float.c │ ├── cls_complex_va_double.c │ ├── cls_align_complex_longdouble.c │ ├── cls_complex_struct_longdouble.c │ ├── cls_complex_va_longdouble.c │ ├── cls_complex_va_float.c │ ├── return_complex.inc │ ├── return_complex1.inc │ ├── return_complex2.inc │ ├── complex.exp │ ├── cls_complex.inc │ ├── complex.inc │ ├── cls_complex_struct.inc │ └── many_complex.inc ├── libffi.call │ ├── err_bad_typedef.c │ ├── return_ldl.c │ ├── return_fl.c │ ├── return_sc.c │ ├── return_sl.c │ ├── return_dbl.c │ ├── return_fl1.c │ ├── return_uc.c │ ├── return_ul.c │ ├── return_ll.c │ ├── strlen.c │ ├── return_fl3.c │ ├── negint.c │ ├── return_dbl2.c │ ├── align_mixed.c │ ├── return_dbl1.c │ ├── align_stdcall.c │ ├── strlen2.c │ ├── strlen3.c │ ├── return_ll1.c │ ├── offsets.c │ ├── struct10.c │ ├── return_fl2.c │ ├── many2.c │ ├── strlen4.c │ ├── float.c │ ├── float1.c │ ├── struct3.c │ ├── uninitialized.c │ ├── float4.c │ ├── many.c │ ├── promotion.c │ ├── struct4.c │ ├── struct6.c │ ├── struct1.c │ ├── struct5.c │ ├── struct9.c │ ├── struct2.c │ ├── float2.c │ ├── many_double.c │ ├── float3.c │ ├── many_mixed.c │ ├── call.exp │ ├── struct7.c │ └── struct8.c ├── libffi.bhaible │ └── Makefile ├── libffi.closures │ ├── err_bad_abi.c │ ├── cls_sint.c │ ├── cls_float.c │ ├── cls_uchar.c │ ├── cls_schar.c │ ├── cls_sshort.c │ ├── cls_ulong_va.c │ ├── cls_double.c │ ├── cls_uchar_va.c │ ├── cls_uint.c │ ├── cls_uint_va.c │ ├── cls_ushort_va.c │ ├── cls_ushort.c │ ├── unwindtest_ffi_call.cc │ ├── cls_dbls_struct.c │ ├── closure_simple.c │ ├── cls_ulonglong.c │ ├── cls_double_va.c │ ├── cls_longdouble_va.c │ ├── cls_many_mixed_float_double.c │ ├── testclosure.c │ ├── cls_multi_schar.c │ ├── cls_multi_sshort.c │ ├── cls_multi_ushort.c │ ├── cls_many_mixed_args.c │ ├── cls_pointer.c │ └── closure.exp └── lib │ └── wrapper.exp ├── doc ├── libffi.pdf ├── Makefile.am ├── stamp-vti └── version.texi ├── msvc_build └── aarch64 │ ├── Ffi_staticLib.vcxproj.user │ └── Ffi_staticLib.sln ├── src ├── arm │ └── internal.h ├── s390 │ └── internal.h ├── x86 │ ├── asmnames.h │ ├── internal64.h │ └── internal.h ├── alpha │ ├── internal.h │ └── ffitarget.h ├── sparc │ └── internal.h ├── bfin │ └── ffitarget.h ├── m88k │ └── ffitarget.h ├── vax │ └── ffitarget.h ├── nios2 │ └── ffitarget.h ├── microblaze │ └── ffitarget.h ├── ia64 │ └── ia64_flags.h ├── xtensa │ └── ffitarget.h ├── metag │ └── ffitarget.h ├── arc │ └── ffitarget.h ├── m32r │ └── ffitarget.h ├── moxie │ └── ffitarget.h ├── sh │ └── ffitarget.h ├── m68k │ └── ffitarget.h ├── avr32 │ └── ffitarget.h ├── or1k │ └── ffitarget.h └── sh64 │ └── ffitarget.h ├── man ├── Makefile.am ├── ffi.3 ├── ffi_prep_cif.3 └── ffi_prep_cif_var.3 ├── include ├── Makefile.am └── ffi_cfi.h ├── libffi.pc.in ├── README.md ├── m4 ├── asmcfi.m4 ├── ltversion.m4 ├── ax_require_defined.m4 ├── ax_append_flag.m4 ├── ax_configure_args.m4 └── ax_check_compile_flag.m4 ├── win32 ├── vc11_x64 │ └── libffi-msvc.sln ├── vc12_x64 │ └── libffi-msvc.sln ├── vc9_x86 │ └── libffi.sln ├── vc11_x86 │ └── libffi-msvc.sln ├── vc12_x86 │ └── libffi-msvc.sln ├── vc14_x64 │ └── libffi-msvc.sln ├── vc15_x64 │ └── libffi-msvc.sln ├── vs16_x64 │ └── libffi-msvc.sln ├── vs17_x64 │ └── libffi-msvc.sln ├── vc14_x86 │ └── libffi-msvc.sln ├── vc15_x86 │ └── libffi-msvc.sln ├── vs16_x86 │ └── libffi-msvc.sln └── vs17_x86 │ └── libffi-msvc.sln ├── winlibs.mak ├── LICENSE ├── libtool-version └── libffi.map.in /testsuite/config/default.exp: -------------------------------------------------------------------------------- 1 | load_lib "standard.exp" 2 | -------------------------------------------------------------------------------- /testsuite/libffi.go/ffitest.h: -------------------------------------------------------------------------------- 1 | #include "../libffi.call/ffitest.h" 2 | -------------------------------------------------------------------------------- /doc/libffi.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/winlibs/libffi/HEAD/doc/libffi.pdf -------------------------------------------------------------------------------- /testsuite/libffi.complex/ffitest.h: -------------------------------------------------------------------------------- 1 | #include "../libffi.call/ffitest.h" 2 | -------------------------------------------------------------------------------- /doc/Makefile.am: -------------------------------------------------------------------------------- 1 | ## Process this with automake to create Makefile.in 2 | 3 | info_TEXINFOS = libffi.texi 4 | -------------------------------------------------------------------------------- /doc/stamp-vti: -------------------------------------------------------------------------------- 1 | @set UPDATED 22 November 2019 2 | @set UPDATED-MONTH November 2019 3 | @set EDITION 3.3 4 | @set VERSION 3.3 5 | -------------------------------------------------------------------------------- /doc/version.texi: -------------------------------------------------------------------------------- 1 | @set UPDATED 22 November 2019 2 | @set UPDATED-MONTH November 2019 3 | @set EDITION 3.3 4 | @set VERSION 3.3 5 | -------------------------------------------------------------------------------- /msvc_build/aarch64/Ffi_staticLib.vcxproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/arm/internal.h: -------------------------------------------------------------------------------- 1 | #define ARM_TYPE_VFP_S 0 2 | #define ARM_TYPE_VFP_D 1 3 | #define ARM_TYPE_VFP_N 2 4 | #define ARM_TYPE_INT64 3 5 | #define ARM_TYPE_INT 4 6 | #define ARM_TYPE_VOID 5 7 | #define ARM_TYPE_STRUCT 6 8 | -------------------------------------------------------------------------------- /man/Makefile.am: -------------------------------------------------------------------------------- 1 | ## Process this with automake to create Makefile.in 2 | 3 | AUTOMAKE_OPTIONS=foreign 4 | 5 | EXTRA_DIST = ffi.3 ffi_call.3 ffi_prep_cif.3 ffi_prep_cif_var.3 6 | 7 | man_MANS = ffi.3 ffi_call.3 ffi_prep_cif.3 ffi_prep_cif_var.3 8 | 9 | -------------------------------------------------------------------------------- /include/Makefile.am: -------------------------------------------------------------------------------- 1 | ## Process this with automake to create Makefile.in 2 | 3 | AUTOMAKE_OPTIONS=foreign 4 | 5 | DISTCLEANFILES=ffitarget.h 6 | noinst_HEADERS=ffi_common.h ffi_cfi.h 7 | EXTRA_DIST=ffi.h.in 8 | 9 | nodist_include_HEADERS = ffi.h ffitarget.h 10 | -------------------------------------------------------------------------------- /testsuite/libffi.complex/complex_float.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check complex types. 3 | Limitations: none. 4 | PR: none. 5 | Originator: . */ 6 | 7 | /* { dg-do run } */ 8 | 9 | #include "complex_defs_float.inc" 10 | #include "complex.inc" 11 | -------------------------------------------------------------------------------- /testsuite/libffi.complex/complex_double.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check complex types. 3 | Limitations: none. 4 | PR: none. 5 | Originator: . */ 6 | 7 | /* { dg-do run } */ 8 | 9 | #include "complex_defs_double.inc" 10 | #include "complex.inc" 11 | -------------------------------------------------------------------------------- /testsuite/libffi.complex/complex_defs_double.inc: -------------------------------------------------------------------------------- 1 | /* -*-c-*- */ 2 | /* Complex base type. */ 3 | #define T_FFI_TYPE ffi_type_complex_double 4 | /* C type corresponding to the base type. */ 5 | #define T_C_TYPE double 6 | /* C cast for a value of type T_C_TYPE that is passed to printf. */ 7 | #define T_CONV 8 | -------------------------------------------------------------------------------- /testsuite/libffi.complex/complex_longdouble.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check complex types. 3 | Limitations: none. 4 | PR: none. 5 | Originator: . */ 6 | 7 | /* { dg-do run } */ 8 | 9 | #include "complex_defs_longdouble.inc" 10 | #include "complex.inc" 11 | -------------------------------------------------------------------------------- /testsuite/libffi.complex/cls_complex_float.c: -------------------------------------------------------------------------------- 1 | /* Area: closure_call 2 | Purpose: Check return value complex. 3 | Limitations: none. 4 | PR: none. 5 | Originator: . */ 6 | 7 | /* { dg-do run } */ 8 | 9 | #include "complex_defs_float.inc" 10 | #include "cls_complex.inc" 11 | -------------------------------------------------------------------------------- /testsuite/libffi.complex/complex_defs_float.inc: -------------------------------------------------------------------------------- 1 | /* -*-c-*- */ 2 | /* Complex base type. */ 3 | #define T_FFI_TYPE ffi_type_complex_float 4 | /* C type corresponding to the base type. */ 5 | #define T_C_TYPE float 6 | /* C cast for a value of type T_C_TYPE that is passed to printf. */ 7 | #define T_CONV (double) 8 | -------------------------------------------------------------------------------- /testsuite/libffi.complex/cls_complex_double.c: -------------------------------------------------------------------------------- 1 | /* Area: closure_call 2 | Purpose: Check return value complex. 3 | Limitations: none. 4 | PR: none. 5 | Originator: . */ 6 | 7 | /* { dg-do run } */ 8 | 9 | #include "complex_defs_double.inc" 10 | #include "cls_complex.inc" 11 | -------------------------------------------------------------------------------- /testsuite/libffi.complex/complex_defs_longdouble.inc: -------------------------------------------------------------------------------- 1 | /* -*-c-*- */ 2 | /* Complex base type. */ 3 | #define T_FFI_TYPE ffi_type_complex_longdouble 4 | /* C type corresponding to the base type. */ 5 | #define T_C_TYPE long double 6 | /* C cast for a value of type T_C_TYPE that is passed to printf. */ 7 | #define T_CONV 8 | -------------------------------------------------------------------------------- /testsuite/libffi.complex/return_complex1_double.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check return value complex. 3 | Limitations: none. 4 | PR: none. 5 | Originator: . */ 6 | 7 | /* { dg-do run } */ 8 | 9 | #include "complex_defs_double.inc" 10 | #include "return_complex1.inc" 11 | -------------------------------------------------------------------------------- /testsuite/libffi.complex/return_complex1_float.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check return value complex. 3 | Limitations: none. 4 | PR: none. 5 | Originator: . */ 6 | 7 | /* { dg-do run } */ 8 | 9 | #include "complex_defs_float.inc" 10 | #include "return_complex1.inc" 11 | -------------------------------------------------------------------------------- /testsuite/libffi.complex/return_complex2_double.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check return value complex. 3 | Limitations: none. 4 | PR: none. 5 | Originator: . */ 6 | 7 | /* { dg-do run } */ 8 | 9 | #include "complex_defs_double.inc" 10 | #include "return_complex2.inc" 11 | -------------------------------------------------------------------------------- /testsuite/libffi.complex/return_complex2_float.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check return value complex. 3 | Limitations: none. 4 | PR: none. 5 | Originator: . */ 6 | 7 | /* { dg-do run } */ 8 | 9 | #include "complex_defs_float.inc" 10 | #include "return_complex2.inc" 11 | -------------------------------------------------------------------------------- /testsuite/libffi.complex/return_complex_double.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check return value complex. 3 | Limitations: none. 4 | PR: none. 5 | Originator: . */ 6 | 7 | /* { dg-do run } */ 8 | 9 | #include "complex_defs_double.inc" 10 | #include "return_complex.inc" 11 | -------------------------------------------------------------------------------- /testsuite/libffi.complex/return_complex_float.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check return value complex. 3 | Limitations: none. 4 | PR: none. 5 | Originator: . */ 6 | 7 | /* { dg-do run } */ 8 | 9 | #include "complex_defs_float.inc" 10 | #include "return_complex.inc" 11 | -------------------------------------------------------------------------------- /testsuite/libffi.complex/cls_complex_longdouble.c: -------------------------------------------------------------------------------- 1 | /* Area: closure_call 2 | Purpose: Check return value complex. 3 | Limitations: none. 4 | PR: none. 5 | Originator: . */ 6 | 7 | /* { dg-do run } */ 8 | 9 | #include "complex_defs_longdouble.inc" 10 | #include "cls_complex.inc" 11 | -------------------------------------------------------------------------------- /testsuite/libffi.complex/return_complex1_longdouble.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check return value complex. 3 | Limitations: none. 4 | PR: none. 5 | Originator: . */ 6 | 7 | /* { dg-do run } */ 8 | 9 | #include "complex_defs_longdouble.inc" 10 | #include "return_complex1.inc" 11 | -------------------------------------------------------------------------------- /testsuite/libffi.complex/return_complex2_longdouble.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check return value complex. 3 | Limitations: none. 4 | PR: none. 5 | Originator: . */ 6 | 7 | /* { dg-do run } */ 8 | 9 | #include "complex_defs_longdouble.inc" 10 | #include "return_complex2.inc" 11 | -------------------------------------------------------------------------------- /testsuite/libffi.complex/return_complex_longdouble.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check return value complex. 3 | Limitations: none. 4 | PR: none. 5 | Originator: . */ 6 | 7 | /* { dg-do run } */ 8 | 9 | #include "complex_defs_longdouble.inc" 10 | #include "return_complex.inc" 11 | -------------------------------------------------------------------------------- /testsuite/libffi.complex/many_complex_double.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check return value complex, with many arguments 3 | Limitations: none. 4 | PR: none. 5 | Originator: . */ 6 | 7 | /* { dg-do run } */ 8 | 9 | #include "complex_defs_double.inc" 10 | #include "many_complex.inc" 11 | -------------------------------------------------------------------------------- /testsuite/libffi.complex/many_complex_float.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check return value complex, with many arguments 3 | Limitations: none. 4 | PR: none. 5 | Originator: . */ 6 | 7 | /* { dg-do run } */ 8 | 9 | #include "complex_defs_float.inc" 10 | #include "many_complex.inc" 11 | -------------------------------------------------------------------------------- /libffi.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@exec_prefix@ 3 | libdir=@libdir@ 4 | toolexeclibdir=@toolexeclibdir@ 5 | includedir=@includedir@ 6 | 7 | Name: @PACKAGE_NAME@ 8 | Description: Library supporting Foreign Function Interfaces 9 | Version: @PACKAGE_VERSION@ 10 | Libs: -L${toolexeclibdir} -lffi 11 | Cflags: -I${includedir} 12 | -------------------------------------------------------------------------------- /testsuite/libffi.complex/many_complex_longdouble.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check return value complex, with many arguments 3 | Limitations: none. 4 | PR: none. 5 | Originator: . */ 6 | 7 | /* { dg-do run } */ 8 | 9 | #include "complex_defs_longdouble.inc" 10 | #include "many_complex.inc" 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # libffi 2 | 3 | libffi Windows repository, used by PHP builds and various other projects 4 | 5 | The Visual Studio solutions are based on [http://github.com/pgregory/libffi-msvc.git](http://github.com/pgregory/libffi-msvc.git) 6 | 7 | ## Building for PHP 8 | 9 | - open and build the appropriate Visual studio solution in .\win32 10 | -------------------------------------------------------------------------------- /testsuite/libffi.complex/cls_align_complex_double.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call, closure_call 2 | Purpose: Check structure alignment of complex. 3 | Limitations: none. 4 | PR: none. 5 | Originator: . */ 6 | 7 | /* { dg-do run } */ 8 | 9 | #include "complex_defs_double.inc" 10 | #include "cls_align_complex.inc" 11 | -------------------------------------------------------------------------------- /testsuite/libffi.complex/cls_align_complex_float.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call, closure_call 2 | Purpose: Check structure alignment of complex. 3 | Limitations: none. 4 | PR: none. 5 | Originator: . */ 6 | 7 | /* { dg-do run } */ 8 | 9 | #include "complex_defs_float.inc" 10 | #include "cls_align_complex.inc" 11 | -------------------------------------------------------------------------------- /testsuite/libffi.complex/cls_complex_struct_double.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call, closure_call 2 | Purpose: Check complex arguments in structs. 3 | Limitations: none. 4 | PR: none. 5 | Originator: . */ 6 | 7 | /* { dg-do run } */ 8 | 9 | #include "complex_defs_double.inc" 10 | #include "cls_complex_struct.inc" 11 | -------------------------------------------------------------------------------- /testsuite/libffi.complex/cls_complex_struct_float.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call, closure_call 2 | Purpose: Check complex arguments in structs. 3 | Limitations: none. 4 | PR: none. 5 | Originator: . */ 6 | 7 | /* { dg-do run } */ 8 | 9 | #include "complex_defs_float.inc" 10 | #include "cls_complex_struct.inc" 11 | -------------------------------------------------------------------------------- /testsuite/libffi.complex/cls_complex_va_double.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call, closure_call 2 | Purpose: Test complex' passed in variable argument lists. 3 | Limitations: none. 4 | PR: none. 5 | Originator: . */ 6 | 7 | /* { dg-do run } */ 8 | 9 | #include "complex_defs_double.inc" 10 | #include "cls_complex_va.inc" 11 | -------------------------------------------------------------------------------- /testsuite/libffi.complex/cls_align_complex_longdouble.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call, closure_call 2 | Purpose: Check structure alignment of complex. 3 | Limitations: none. 4 | PR: none. 5 | Originator: . */ 6 | 7 | /* { dg-do run } */ 8 | 9 | #include "complex_defs_longdouble.inc" 10 | #include "cls_align_complex.inc" 11 | -------------------------------------------------------------------------------- /testsuite/libffi.complex/cls_complex_struct_longdouble.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call, closure_call 2 | Purpose: Check complex arguments in structs. 3 | Limitations: none. 4 | PR: none. 5 | Originator: . */ 6 | 7 | /* { dg-do run } */ 8 | 9 | #include "complex_defs_longdouble.inc" 10 | #include "cls_complex_struct.inc" 11 | -------------------------------------------------------------------------------- /testsuite/libffi.complex/cls_complex_va_longdouble.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call, closure_call 2 | Purpose: Test complex' passed in variable argument lists. 3 | Limitations: none. 4 | PR: none. 5 | Originator: . */ 6 | 7 | /* { dg-do run } */ 8 | 9 | #include "complex_defs_longdouble.inc" 10 | #include "cls_complex_va.inc" 11 | -------------------------------------------------------------------------------- /src/s390/internal.h: -------------------------------------------------------------------------------- 1 | /* If these values change, sysv.S must be adapted! */ 2 | #define FFI390_RET_DOUBLE 0 3 | #define FFI390_RET_FLOAT 1 4 | #define FFI390_RET_INT64 2 5 | #define FFI390_RET_INT32 3 6 | #define FFI390_RET_VOID 4 7 | 8 | #define FFI360_RET_MASK 7 9 | #define FFI390_RET_IN_MEM 8 10 | 11 | #define FFI390_RET_STRUCT (FFI390_RET_VOID | FFI390_RET_IN_MEM) 12 | -------------------------------------------------------------------------------- /m4/asmcfi.m4: -------------------------------------------------------------------------------- 1 | AC_DEFUN([GCC_AS_CFI_PSEUDO_OP], 2 | [AC_CACHE_CHECK([assembler .cfi pseudo-op support], 3 | gcc_cv_as_cfi_pseudo_op, [ 4 | gcc_cv_as_cfi_pseudo_op=unknown 5 | AC_TRY_COMPILE([asm (".cfi_sections\n\t.cfi_startproc\n\t.cfi_endproc");],, 6 | [gcc_cv_as_cfi_pseudo_op=yes], 7 | [gcc_cv_as_cfi_pseudo_op=no]) 8 | ]) 9 | if test "x$gcc_cv_as_cfi_pseudo_op" = xyes; then 10 | AC_DEFINE(HAVE_AS_CFI_PSEUDO_OP, 1, 11 | [Define if your assembler supports .cfi_* directives.]) 12 | fi 13 | ]) 14 | -------------------------------------------------------------------------------- /testsuite/libffi.call/err_bad_typedef.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_prep_cif 2 | Purpose: Test error return for bad typedefs. 3 | Limitations: none. 4 | PR: none. 5 | Originator: Blake Chaffin 6/6/2007 */ 6 | 7 | /* { dg-do run } */ 8 | 9 | #include "ffitest.h" 10 | 11 | int main (void) 12 | { 13 | ffi_cif cif; 14 | ffi_type* arg_types[1]; 15 | 16 | ffi_type badType = ffi_type_void; 17 | 18 | arg_types[0] = NULL; 19 | 20 | badType.size = 0; 21 | 22 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 0, &badType, 23 | arg_types) == FFI_BAD_TYPEDEF); 24 | 25 | exit(0); 26 | } 27 | -------------------------------------------------------------------------------- /testsuite/libffi.go/static-chain.h: -------------------------------------------------------------------------------- 1 | #ifdef __aarch64__ 2 | # define STATIC_CHAIN_REG "x18" 3 | #elif defined(__alpha__) 4 | # define STATIC_CHAIN_REG "$1" 5 | #elif defined(__arm__) 6 | # define STATIC_CHAIN_REG "ip" 7 | #elif defined(__sparc__) 8 | # if defined(__arch64__) || defined(__sparcv9) 9 | # define STATIC_CHAIN_REG "g5" 10 | # else 11 | # define STATIC_CHAIN_REG "g2" 12 | # endif 13 | #elif defined(__x86_64__) 14 | # define STATIC_CHAIN_REG "r10" 15 | #elif defined(__i386__) 16 | # ifndef ABI_NUM 17 | # define STATIC_CHAIN_REG "ecx" /* FFI_DEFAULT_ABI only */ 18 | # endif 19 | #endif 20 | -------------------------------------------------------------------------------- /testsuite/libffi.complex/cls_complex_va_float.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call, closure_call 2 | Purpose: Test complex' passed in variable argument lists. 3 | Limitations: none. 4 | PR: none. 5 | Originator: . */ 6 | 7 | /* { dg-do run } */ 8 | 9 | /* Alpha splits _Complex into two arguments. It's illegal to pass 10 | float through varargs, so _Complex float goes badly. In sort of 11 | gets passed as _Complex double, but the compiler doesn't agree 12 | with itself on this issue. */ 13 | /* { dg-do run { xfail alpha*-*-* } } */ 14 | 15 | #include "complex_defs_float.inc" 16 | #include "cls_complex_va.inc" 17 | -------------------------------------------------------------------------------- /src/x86/asmnames.h: -------------------------------------------------------------------------------- 1 | #ifndef ASMNAMES_H 2 | #define ASMNAMES_H 3 | 4 | #define C2(X, Y) X ## Y 5 | #define C1(X, Y) C2(X, Y) 6 | #ifdef __USER_LABEL_PREFIX__ 7 | # define C(X) C1(__USER_LABEL_PREFIX__, X) 8 | #else 9 | # define C(X) X 10 | #endif 11 | 12 | #ifdef __APPLE__ 13 | # define L(X) C1(L, X) 14 | #else 15 | # define L(X) C1(.L, X) 16 | #endif 17 | 18 | #if defined(__ELF__) && defined(__PIC__) 19 | # define PLT(X) X@PLT 20 | #else 21 | # define PLT(X) X 22 | #endif 23 | 24 | #ifdef __ELF__ 25 | # define ENDF(X) .type X,@function; .size X, . - X 26 | #else 27 | # define ENDF(X) 28 | #endif 29 | 30 | #endif /* ASMNAMES_H */ 31 | -------------------------------------------------------------------------------- /testsuite/libffi.go/closure1.c: -------------------------------------------------------------------------------- 1 | /* { dg-do run } */ 2 | 3 | #include "ffitest.h" 4 | 5 | void doit(ffi_cif *cif, void *rvalue, void **avalue, void *closure) 6 | { 7 | (void)cif; 8 | (void)avalue; 9 | *(void **)rvalue = closure; 10 | } 11 | 12 | typedef void * (*FN)(void); 13 | 14 | int main() 15 | { 16 | ffi_cif cif; 17 | ffi_go_closure cl; 18 | void *result; 19 | 20 | CHECK(ffi_prep_cif(&cif, ABI_NUM, 0, &ffi_type_pointer, NULL) == FFI_OK); 21 | CHECK(ffi_prep_go_closure(&cl, &cif, doit) == FFI_OK); 22 | 23 | ffi_call_go(&cif, FFI_FN(*(FN *)&cl), &result, NULL, &cl); 24 | 25 | CHECK(result == &cl); 26 | 27 | exit(0); 28 | } 29 | -------------------------------------------------------------------------------- /src/alpha/internal.h: -------------------------------------------------------------------------------- 1 | #define ALPHA_ST_VOID 0 2 | #define ALPHA_ST_INT 1 3 | #define ALPHA_ST_FLOAT 2 4 | #define ALPHA_ST_DOUBLE 3 5 | #define ALPHA_ST_CPLXF 4 6 | #define ALPHA_ST_CPLXD 5 7 | 8 | #define ALPHA_LD_VOID 0 9 | #define ALPHA_LD_INT64 1 10 | #define ALPHA_LD_INT32 2 11 | #define ALPHA_LD_UINT16 3 12 | #define ALPHA_LD_SINT16 4 13 | #define ALPHA_LD_UINT8 5 14 | #define ALPHA_LD_SINT8 6 15 | #define ALPHA_LD_FLOAT 7 16 | #define ALPHA_LD_DOUBLE 8 17 | #define ALPHA_LD_CPLXF 9 18 | #define ALPHA_LD_CPLXD 10 19 | 20 | #define ALPHA_ST_SHIFT 0 21 | #define ALPHA_LD_SHIFT 8 22 | #define ALPHA_RET_IN_MEM 0x10000 23 | #define ALPHA_FLAGS(S, L) (((L) << ALPHA_LD_SHIFT) | (S)) 24 | -------------------------------------------------------------------------------- /src/x86/internal64.h: -------------------------------------------------------------------------------- 1 | #define UNIX64_RET_VOID 0 2 | #define UNIX64_RET_UINT8 1 3 | #define UNIX64_RET_UINT16 2 4 | #define UNIX64_RET_UINT32 3 5 | #define UNIX64_RET_SINT8 4 6 | #define UNIX64_RET_SINT16 5 7 | #define UNIX64_RET_SINT32 6 8 | #define UNIX64_RET_INT64 7 9 | #define UNIX64_RET_XMM32 8 10 | #define UNIX64_RET_XMM64 9 11 | #define UNIX64_RET_X87 10 12 | #define UNIX64_RET_X87_2 11 13 | #define UNIX64_RET_ST_XMM0_RAX 12 14 | #define UNIX64_RET_ST_RAX_XMM0 13 15 | #define UNIX64_RET_ST_XMM0_XMM1 14 16 | #define UNIX64_RET_ST_RAX_RDX 15 17 | 18 | #define UNIX64_RET_LAST 15 19 | 20 | #define UNIX64_FLAG_RET_IN_MEM (1 << 10) 21 | #define UNIX64_FLAG_XMM_ARGS (1 << 11) 22 | #define UNIX64_SIZE_SHIFT 12 23 | -------------------------------------------------------------------------------- /src/x86/internal.h: -------------------------------------------------------------------------------- 1 | #define X86_RET_FLOAT 0 2 | #define X86_RET_DOUBLE 1 3 | #define X86_RET_LDOUBLE 2 4 | #define X86_RET_SINT8 3 5 | #define X86_RET_SINT16 4 6 | #define X86_RET_UINT8 5 7 | #define X86_RET_UINT16 6 8 | #define X86_RET_INT64 7 9 | #define X86_RET_INT32 8 10 | #define X86_RET_VOID 9 11 | #define X86_RET_STRUCTPOP 10 12 | #define X86_RET_STRUCTARG 11 13 | #define X86_RET_STRUCT_1B 12 14 | #define X86_RET_STRUCT_2B 13 15 | #define X86_RET_UNUSED14 14 16 | #define X86_RET_UNUSED15 15 17 | 18 | #define X86_RET_TYPE_MASK 15 19 | #define X86_RET_POP_SHIFT 4 20 | 21 | #define R_EAX 0 22 | #define R_EDX 1 23 | #define R_ECX 2 24 | 25 | #ifdef __PCC__ 26 | # define HAVE_FASTCALL 0 27 | #else 28 | # define HAVE_FASTCALL 1 29 | #endif 30 | -------------------------------------------------------------------------------- /m4/ltversion.m4: -------------------------------------------------------------------------------- 1 | # ltversion.m4 -- version numbers -*- Autoconf -*- 2 | # 3 | # Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc. 4 | # Written by Scott James Remnant, 2004 5 | # 6 | # This file is free software; the Free Software Foundation gives 7 | # unlimited permission to copy and/or distribute it, with or without 8 | # modifications, as long as this notice is preserved. 9 | 10 | # @configure_input@ 11 | 12 | # serial 4179 ltversion.m4 13 | # This file is part of GNU Libtool 14 | 15 | m4_define([LT_PACKAGE_VERSION], [2.4.6]) 16 | m4_define([LT_PACKAGE_REVISION], [2.4.6]) 17 | 18 | AC_DEFUN([LTVERSION_VERSION], 19 | [macro_version='2.4.6' 20 | macro_revision='2.4.6' 21 | _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) 22 | _LT_DECL(, macro_revision, 0) 23 | ]) 24 | -------------------------------------------------------------------------------- /src/sparc/internal.h: -------------------------------------------------------------------------------- 1 | #define SPARC_RET_VOID 0 2 | #define SPARC_RET_STRUCT 1 3 | #define SPARC_RET_UINT8 2 4 | #define SPARC_RET_SINT8 3 5 | #define SPARC_RET_UINT16 4 6 | #define SPARC_RET_SINT16 5 7 | #define SPARC_RET_UINT32 6 8 | #define SP_V9_RET_SINT32 7 /* v9 only */ 9 | #define SP_V8_RET_CPLX16 7 /* v8 only */ 10 | #define SPARC_RET_INT64 8 11 | #define SPARC_RET_INT128 9 12 | 13 | /* Note that F_7 is missing, and is handled by SPARC_RET_STRUCT. */ 14 | #define SPARC_RET_F_8 10 15 | #define SPARC_RET_F_6 11 16 | #define SPARC_RET_F_4 12 17 | #define SPARC_RET_F_2 13 18 | #define SP_V9_RET_F_3 14 /* v9 only */ 19 | #define SP_V8_RET_CPLX8 14 /* v8 only */ 20 | #define SPARC_RET_F_1 15 21 | 22 | #define SPARC_FLAG_RET_MASK 15 23 | #define SPARC_FLAG_RET_IN_MEM 32 24 | #define SPARC_FLAG_FP_ARGS 64 25 | 26 | #define SPARC_SIZEMASK_SHIFT 8 27 | -------------------------------------------------------------------------------- /testsuite/libffi.call/return_ldl.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check return value long double. 3 | Limitations: none. 4 | PR: none. 5 | Originator: 20071113 */ 6 | /* { dg-do run } */ 7 | 8 | #include "ffitest.h" 9 | 10 | static long double return_ldl(long double ldl) 11 | { 12 | return 2*ldl; 13 | } 14 | int main (void) 15 | { 16 | ffi_cif cif; 17 | ffi_type *args[MAX_ARGS]; 18 | void *values[MAX_ARGS]; 19 | long double ldl, rldl; 20 | 21 | args[0] = &ffi_type_longdouble; 22 | values[0] = &ldl; 23 | 24 | /* Initialize the cif */ 25 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 26 | &ffi_type_longdouble, args) == FFI_OK); 27 | 28 | for (ldl = -127.0; ldl < 127.0; ldl++) 29 | { 30 | ffi_call(&cif, FFI_FN(return_ldl), &rldl, values); 31 | CHECK(rldl == 2 * ldl); 32 | } 33 | exit(0); 34 | } 35 | -------------------------------------------------------------------------------- /testsuite/libffi.call/return_fl.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check return value float. 3 | Limitations: none. 4 | PR: none. 5 | Originator: 20050212 */ 6 | 7 | /* { dg-do run } */ 8 | #include "ffitest.h" 9 | 10 | static float return_fl(float fl) 11 | { 12 | return 2 * fl; 13 | } 14 | int main (void) 15 | { 16 | ffi_cif cif; 17 | ffi_type *args[MAX_ARGS]; 18 | void *values[MAX_ARGS]; 19 | float fl, rfl; 20 | 21 | args[0] = &ffi_type_float; 22 | values[0] = &fl; 23 | 24 | /* Initialize the cif */ 25 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 26 | &ffi_type_float, args) == FFI_OK); 27 | 28 | for (fl = -127.0; fl < 127; fl++) 29 | { 30 | ffi_call(&cif, FFI_FN(return_fl), &rfl, values); 31 | printf ("%f vs %f\n", rfl, return_fl(fl)); 32 | CHECK(rfl == 2 * fl); 33 | } 34 | exit(0); 35 | } 36 | -------------------------------------------------------------------------------- /testsuite/libffi.go/aa-direct.c: -------------------------------------------------------------------------------- 1 | /* { dg-do run } */ 2 | 3 | #include "static-chain.h" 4 | 5 | #if defined(__GNUC__) && !defined(__clang__) && defined(STATIC_CHAIN_REG) 6 | 7 | #include "ffitest.h" 8 | 9 | /* Blatent assumption here that the prologue doesn't clobber the 10 | static chain for trivial functions. If this is not true, don't 11 | define STATIC_CHAIN_REG, and we'll test what we can via other tests. */ 12 | void *doit(void) 13 | { 14 | register void *chain __asm__(STATIC_CHAIN_REG); 15 | return chain; 16 | } 17 | 18 | int main() 19 | { 20 | ffi_cif cif; 21 | void *result; 22 | 23 | CHECK(ffi_prep_cif(&cif, ABI_NUM, 0, &ffi_type_pointer, NULL) == FFI_OK); 24 | 25 | ffi_call_go(&cif, FFI_FN(doit), &result, NULL, &result); 26 | 27 | CHECK(result == &result); 28 | 29 | return 0; 30 | } 31 | 32 | #else /* UNSUPPORTED */ 33 | int main() { return 0; } 34 | #endif 35 | -------------------------------------------------------------------------------- /testsuite/libffi.call/return_sc.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check return value signed char. 3 | Limitations: none. 4 | PR: none. 5 | Originator: From the original ffitest.c */ 6 | 7 | /* { dg-do run } */ 8 | #include "ffitest.h" 9 | 10 | static signed char return_sc(signed char sc) 11 | { 12 | return sc; 13 | } 14 | int main (void) 15 | { 16 | ffi_cif cif; 17 | ffi_type *args[MAX_ARGS]; 18 | void *values[MAX_ARGS]; 19 | ffi_arg rint; 20 | signed char sc; 21 | 22 | args[0] = &ffi_type_schar; 23 | values[0] = ≻ 24 | 25 | /* Initialize the cif */ 26 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 27 | &ffi_type_schar, args) == FFI_OK); 28 | 29 | for (sc = (signed char) -127; 30 | sc < (signed char) 127; sc++) 31 | { 32 | ffi_call(&cif, FFI_FN(return_sc), &rint, values); 33 | CHECK((signed char)rint == sc); 34 | } 35 | exit(0); 36 | } 37 | -------------------------------------------------------------------------------- /testsuite/libffi.call/return_sl.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check if long as return type is handled correctly. 3 | Limitations: none. 4 | PR: none. 5 | */ 6 | 7 | /* { dg-do run } */ 8 | #include "ffitest.h" 9 | static long return_sl(long l1, long l2) 10 | { 11 | return l1 - l2; 12 | } 13 | 14 | int main (void) 15 | { 16 | ffi_cif cif; 17 | ffi_type *args[MAX_ARGS]; 18 | void *values[MAX_ARGS]; 19 | ffi_arg res; 20 | unsigned long l1, l2; 21 | 22 | args[0] = &ffi_type_slong; 23 | args[1] = &ffi_type_slong; 24 | values[0] = &l1; 25 | values[1] = &l2; 26 | 27 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, 28 | &ffi_type_slong, args) == FFI_OK); 29 | 30 | l1 = 1073741823L; 31 | l2 = 1073741824L; 32 | 33 | ffi_call(&cif, FFI_FN(return_sl), &res, values); 34 | printf("res: %ld, %ld\n", (long)res, l1 - l2); 35 | /* { dg-output "res: -1, -1" } */ 36 | 37 | exit(0); 38 | } 39 | -------------------------------------------------------------------------------- /testsuite/libffi.call/return_dbl.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check return value double. 3 | Limitations: none. 4 | PR: none. 5 | Originator: 20050212 */ 6 | 7 | /* { dg-do run } */ 8 | #include "ffitest.h" 9 | 10 | static double return_dbl(double dbl) 11 | { 12 | printf ("%f\n", dbl); 13 | return 2 * dbl; 14 | } 15 | int main (void) 16 | { 17 | ffi_cif cif; 18 | ffi_type *args[MAX_ARGS]; 19 | void *values[MAX_ARGS]; 20 | double dbl, rdbl; 21 | 22 | args[0] = &ffi_type_double; 23 | values[0] = &dbl; 24 | 25 | /* Initialize the cif */ 26 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 27 | &ffi_type_double, args) == FFI_OK); 28 | 29 | for (dbl = -127.3; dbl < 127; dbl++) 30 | { 31 | ffi_call(&cif, FFI_FN(return_dbl), &rdbl, values); 32 | printf ("%f vs %f\n", rdbl, return_dbl(dbl)); 33 | CHECK(rdbl == 2 * dbl); 34 | } 35 | exit(0); 36 | } 37 | -------------------------------------------------------------------------------- /testsuite/libffi.call/return_fl1.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check return value float. 3 | Limitations: none. 4 | PR: none. 5 | Originator: 20050212 */ 6 | 7 | /* { dg-do run } */ 8 | #include "ffitest.h" 9 | 10 | static float return_fl(float fl1, float fl2) 11 | { 12 | return fl1 + fl2; 13 | } 14 | int main (void) 15 | { 16 | ffi_cif cif; 17 | ffi_type *args[MAX_ARGS]; 18 | void *values[MAX_ARGS]; 19 | float fl1, fl2, rfl; 20 | 21 | args[0] = &ffi_type_float; 22 | args[1] = &ffi_type_float; 23 | values[0] = &fl1; 24 | values[1] = &fl2; 25 | 26 | /* Initialize the cif */ 27 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, 28 | &ffi_type_float, args) == FFI_OK); 29 | fl1 = 127.0; 30 | fl2 = 128.0; 31 | 32 | ffi_call(&cif, FFI_FN(return_fl), &rfl, values); 33 | printf ("%f vs %f\n", rfl, return_fl(fl1, fl2)); 34 | CHECK(rfl == fl1 + fl2); 35 | exit(0); 36 | } 37 | -------------------------------------------------------------------------------- /testsuite/libffi.call/return_uc.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check return value unsigned char. 3 | Limitations: none. 4 | PR: none. 5 | Originator: From the original ffitest.c */ 6 | 7 | /* { dg-do run } */ 8 | #include "ffitest.h" 9 | 10 | static unsigned char return_uc(unsigned char uc) 11 | { 12 | return uc; 13 | } 14 | 15 | int main (void) 16 | { 17 | ffi_cif cif; 18 | ffi_type *args[MAX_ARGS]; 19 | void *values[MAX_ARGS]; 20 | ffi_arg rint; 21 | 22 | unsigned char uc; 23 | 24 | args[0] = &ffi_type_uchar; 25 | values[0] = &uc; 26 | 27 | /* Initialize the cif */ 28 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 29 | &ffi_type_uchar, args) == FFI_OK); 30 | 31 | for (uc = (unsigned char) '\x00'; 32 | uc < (unsigned char) '\xff'; uc++) 33 | { 34 | ffi_call(&cif, FFI_FN(return_uc), &rint, values); 35 | CHECK((unsigned char)rint == uc); 36 | } 37 | exit(0); 38 | } 39 | -------------------------------------------------------------------------------- /win32/vc11_x64/libffi-msvc.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libffi", "libffi\libffi.vcxproj", "{793F0ABE-66E5-48C0-9690-3060FF08AFF5}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|x64 = Debug|x64 9 | Release|x64 = Release|x64 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Debug|x64.ActiveCfg = Debug|x64 13 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Debug|x64.Build.0 = Debug|x64 14 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Release|x64.ActiveCfg = Release|x64 15 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Release|x64.Build.0 = Release|x64 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /win32/vc12_x64/libffi-msvc.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libffi", "libffi\libffi.vcxproj", "{793F0ABE-66E5-48C0-9690-3060FF08AFF5}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|x64 = Debug|x64 9 | Release|x64 = Release|x64 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Debug|x64.ActiveCfg = Debug|x64 13 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Debug|x64.Build.0 = Debug|x64 14 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Release|x64.ActiveCfg = Release|x64 15 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Release|x64.Build.0 = Release|x64 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /testsuite/libffi.bhaible/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | CFLAGS = -O2 -Wall 3 | prefix = 4 | includedir = $(prefix)/include 5 | libdir = $(prefix)/lib 6 | CPPFLAGS = -I$(includedir) 7 | LDFLAGS = -L$(libdir) -Wl,-rpath,$(libdir) 8 | 9 | all: check-call check-callback 10 | 11 | test-call: test-call.c testcases.c 12 | $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o test-call test-call.c -lffi 13 | 14 | test-callback: test-callback.c testcases.c 15 | $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o test-callback test-callback.c -lffi 16 | 17 | check-call: test-call 18 | ./test-call > test-call.out 19 | LC_ALL=C uniq -u < test-call.out > failed-call 20 | test '!' -s failed-call 21 | 22 | check-callback: test-callback 23 | ./test-callback > test-callback.out 24 | LC_ALL=C uniq -u < test-callback.out > failed-callback 25 | test '!' -s failed-callback 26 | 27 | clean: 28 | rm -f test-call test-callback test-call.out test-callback.out failed-call failed-callback 29 | -------------------------------------------------------------------------------- /win32/vc9_x86/libffi.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 10.00 3 | # Visual Studio 2008 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libffi", "libffi\libffi.vcproj", "{1D251A7E-C06F-4991-932B-0FA87A0883FC}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Release|Win32 = Release|Win32 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {1D251A7E-C06F-4991-932B-0FA87A0883FC}.Debug|Win32.ActiveCfg = Debug|Win32 13 | {1D251A7E-C06F-4991-932B-0FA87A0883FC}.Debug|Win32.Build.0 = Debug|Win32 14 | {1D251A7E-C06F-4991-932B-0FA87A0883FC}.Release|Win32.ActiveCfg = Release|Win32 15 | {1D251A7E-C06F-4991-932B-0FA87A0883FC}.Release|Win32.Build.0 = Release|Win32 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /win32/vc11_x86/libffi-msvc.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libffi", "libffi\libffi.vcxproj", "{793F0ABE-66E5-48C0-9690-3060FF08AFF5}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Release|Win32 = Release|Win32 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Debug|Win32.ActiveCfg = Debug|Win32 13 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Debug|Win32.Build.0 = Debug|Win32 14 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Release|Win32.ActiveCfg = Release|Win32 15 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Release|Win32.Build.0 = Release|Win32 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /win32/vc12_x86/libffi-msvc.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libffi", "libffi\libffi.vcxproj", "{793F0ABE-66E5-48C0-9690-3060FF08AFF5}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Release|Win32 = Release|Win32 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Debug|Win32.ActiveCfg = Debug|Win32 13 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Debug|Win32.Build.0 = Debug|Win32 14 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Release|Win32.ActiveCfg = Release|Win32 15 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Release|Win32.Build.0 = Release|Win32 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /testsuite/libffi.closures/err_bad_abi.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_prep_cif, ffi_prep_closure 2 | Purpose: Test error return for bad ABIs. 3 | Limitations: none. 4 | PR: none. 5 | Originator: Blake Chaffin 6/6/2007 */ 6 | 7 | /* { dg-do run } */ 8 | 9 | #include "ffitest.h" 10 | 11 | static void 12 | dummy_fn(ffi_cif* cif __UNUSED__, void* resp __UNUSED__, 13 | void** args __UNUSED__, void* userdata __UNUSED__) 14 | {} 15 | 16 | int main (void) 17 | { 18 | ffi_cif cif; 19 | void *code; 20 | ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); 21 | ffi_type* arg_types[1]; 22 | 23 | arg_types[0] = NULL; 24 | 25 | CHECK(ffi_prep_cif(&cif, 255, 0, &ffi_type_void, 26 | arg_types) == FFI_BAD_ABI); 27 | 28 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 0, &ffi_type_void, 29 | arg_types) == FFI_OK); 30 | 31 | cif.abi= 255; 32 | 33 | CHECK(ffi_prep_closure_loc(pcl, &cif, dummy_fn, NULL, code) == FFI_BAD_ABI); 34 | 35 | exit(0); 36 | } 37 | -------------------------------------------------------------------------------- /testsuite/libffi.complex/return_complex.inc: -------------------------------------------------------------------------------- 1 | /* -*-c-*- */ 2 | #include "ffitest.h" 3 | #include 4 | 5 | static _Complex T_C_TYPE return_c(_Complex T_C_TYPE c) 6 | { 7 | printf ("%f,%fi\n", T_CONV creal (c), T_CONV cimag (c)); 8 | return 2 * c; 9 | } 10 | int main (void) 11 | { 12 | ffi_cif cif; 13 | ffi_type *args[MAX_ARGS]; 14 | void *values[MAX_ARGS]; 15 | _Complex T_C_TYPE c, rc, rc2; 16 | T_C_TYPE cr, ci; 17 | 18 | args[0] = &T_FFI_TYPE; 19 | values[0] = &c; 20 | 21 | /* Initialize the cif */ 22 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 23 | &T_FFI_TYPE, args) == FFI_OK); 24 | 25 | for (cr = -127.0; cr < 127; cr++) 26 | { 27 | ci = 1000.0 - cr; 28 | c = cr + ci * I; 29 | ffi_call(&cif, FFI_FN(return_c), &rc, values); 30 | rc2 = return_c(c); 31 | printf ("%f,%fi vs %f,%fi\n", 32 | T_CONV creal (rc), T_CONV cimag (rc), 33 | T_CONV creal (rc2), T_CONV cimag (rc2)); 34 | CHECK(rc == 2 * c); 35 | } 36 | exit(0); 37 | } 38 | -------------------------------------------------------------------------------- /win32/vc14_x64/libffi-msvc.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.23107.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libffi", "libffi\libffi.vcxproj", "{793F0ABE-66E5-48C0-9690-3060FF08AFF5}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Release|x64 = Release|x64 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Debug|x64.ActiveCfg = Debug|x64 15 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Debug|x64.Build.0 = Debug|x64 16 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Release|x64.ActiveCfg = Release|x64 17 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Release|x64.Build.0 = Release|x64 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /win32/vc15_x64/libffi-msvc.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.23107.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libffi", "libffi\libffi.vcxproj", "{793F0ABE-66E5-48C0-9690-3060FF08AFF5}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Release|x64 = Release|x64 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Debug|x64.ActiveCfg = Debug|x64 15 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Debug|x64.Build.0 = Debug|x64 16 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Release|x64.ActiveCfg = Release|x64 17 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Release|x64.Build.0 = Release|x64 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /win32/vs16_x64/libffi-msvc.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.23107.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libffi", "libffi\libffi.vcxproj", "{793F0ABE-66E5-48C0-9690-3060FF08AFF5}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Release|x64 = Release|x64 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Debug|x64.ActiveCfg = Debug|x64 15 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Debug|x64.Build.0 = Debug|x64 16 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Release|x64.ActiveCfg = Release|x64 17 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Release|x64.Build.0 = Release|x64 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /win32/vs17_x64/libffi-msvc.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.23107.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libffi", "libffi\libffi.vcxproj", "{793F0ABE-66E5-48C0-9690-3060FF08AFF5}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Release|x64 = Release|x64 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Debug|x64.ActiveCfg = Debug|x64 15 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Debug|x64.Build.0 = Debug|x64 16 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Release|x64.ActiveCfg = Release|x64 17 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Release|x64.Build.0 = Release|x64 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /man/ffi.3: -------------------------------------------------------------------------------- 1 | .Dd February 15, 2008 2 | .Dt FFI 3 3 | .Sh NAME 4 | .Nm FFI 5 | .Nd Foreign Function Interface 6 | .Sh LIBRARY 7 | libffi, -lffi 8 | .Sh SYNOPSIS 9 | .In ffi.h 10 | .Ft ffi_status 11 | .Fo ffi_prep_cif 12 | .Fa "ffi_cif *cif" 13 | .Fa "ffi_abi abi" 14 | .Fa "unsigned int nargs" 15 | .Fa "ffi_type *rtype" 16 | .Fa "ffi_type **atypes" 17 | .Fc 18 | .Ft void 19 | .Fo ffi_prep_cif_var 20 | .Fa "ffi_cif *cif" 21 | .Fa "ffi_abi abi" 22 | .Fa "unsigned int nfixedargs" 23 | .Fa "unsigned int ntotalargs" 24 | .Fa "ffi_type *rtype" 25 | .Fa "ffi_type **atypes" 26 | .Fc 27 | .Ft void 28 | .Fo ffi_call 29 | .Fa "ffi_cif *cif" 30 | .Fa "void (*fn)(void)" 31 | .Fa "void *rvalue" 32 | .Fa "void **avalue" 33 | .Fc 34 | .Sh DESCRIPTION 35 | The foreign function interface provides a mechanism by which a function can 36 | generate a call to another function at runtime without requiring knowledge of 37 | the called function's interface at compile time. 38 | .Sh SEE ALSO 39 | .Xr ffi_prep_cif 3 , 40 | .Xr ffi_prep_cif_var 3 , 41 | .Xr ffi_call 3 42 | -------------------------------------------------------------------------------- /win32/vc14_x86/libffi-msvc.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.23107.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libffi", "libffi\libffi.vcxproj", "{793F0ABE-66E5-48C0-9690-3060FF08AFF5}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Win32 = Debug|Win32 11 | Release|Win32 = Release|Win32 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Debug|Win32.ActiveCfg = Debug|Win32 15 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Debug|Win32.Build.0 = Debug|Win32 16 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Release|Win32.ActiveCfg = Release|Win32 17 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Release|Win32.Build.0 = Release|Win32 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /win32/vc15_x86/libffi-msvc.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.23107.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libffi", "libffi\libffi.vcxproj", "{793F0ABE-66E5-48C0-9690-3060FF08AFF5}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Win32 = Debug|Win32 11 | Release|Win32 = Release|Win32 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Debug|Win32.ActiveCfg = Debug|Win32 15 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Debug|Win32.Build.0 = Debug|Win32 16 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Release|Win32.ActiveCfg = Release|Win32 17 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Release|Win32.Build.0 = Release|Win32 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /win32/vs16_x86/libffi-msvc.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.23107.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libffi", "libffi\libffi.vcxproj", "{793F0ABE-66E5-48C0-9690-3060FF08AFF5}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Win32 = Debug|Win32 11 | Release|Win32 = Release|Win32 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Debug|Win32.ActiveCfg = Debug|Win32 15 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Debug|Win32.Build.0 = Debug|Win32 16 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Release|Win32.ActiveCfg = Release|Win32 17 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Release|Win32.Build.0 = Release|Win32 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /win32/vs17_x86/libffi-msvc.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.23107.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libffi", "libffi\libffi.vcxproj", "{793F0ABE-66E5-48C0-9690-3060FF08AFF5}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Win32 = Debug|Win32 11 | Release|Win32 = Release|Win32 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Debug|Win32.ActiveCfg = Debug|Win32 15 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Debug|Win32.Build.0 = Debug|Win32 16 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Release|Win32.ActiveCfg = Release|Win32 17 | {793F0ABE-66E5-48C0-9690-3060FF08AFF5}.Release|Win32.Build.0 = Release|Win32 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /testsuite/libffi.call/return_ul.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check if unsigned long as return type is handled correctly. 3 | Limitations: none. 4 | PR: none. 5 | Originator: 20060724 */ 6 | 7 | /* { dg-do run } */ 8 | #include "ffitest.h" 9 | static unsigned long return_ul(unsigned long ul1, unsigned long ul2) 10 | { 11 | return ul1 + ul2; 12 | } 13 | 14 | int main (void) 15 | { 16 | ffi_cif cif; 17 | ffi_type *args[MAX_ARGS]; 18 | void *values[MAX_ARGS]; 19 | ffi_arg res; 20 | unsigned long ul1, ul2; 21 | 22 | args[0] = &ffi_type_ulong; 23 | args[1] = &ffi_type_ulong; 24 | values[0] = &ul1; 25 | values[1] = &ul2; 26 | 27 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, 28 | &ffi_type_ulong, args) == FFI_OK); 29 | 30 | ul1 = 1073741823L; 31 | ul2 = 1073741824L; 32 | 33 | ffi_call(&cif, FFI_FN(return_ul), &res, values); 34 | printf("res: %lu, %lu\n", (unsigned long)res, ul1 + ul2); 35 | /* { dg-output "res: 2147483647, 2147483647" } */ 36 | 37 | exit(0); 38 | } 39 | -------------------------------------------------------------------------------- /testsuite/libffi.call/return_ll.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check return value long long. 3 | Limitations: none. 4 | PR: none. 5 | Originator: From the original ffitest.c */ 6 | 7 | /* { dg-do run } */ 8 | #include "ffitest.h" 9 | static long long return_ll(long long ll) 10 | { 11 | return ll; 12 | } 13 | 14 | int main (void) 15 | { 16 | ffi_cif cif; 17 | ffi_type *args[MAX_ARGS]; 18 | void *values[MAX_ARGS]; 19 | long long rlonglong; 20 | long long ll; 21 | 22 | args[0] = &ffi_type_sint64; 23 | values[0] = ≪ 24 | 25 | /* Initialize the cif */ 26 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 27 | &ffi_type_sint64, args) == FFI_OK); 28 | 29 | for (ll = 0LL; ll < 100LL; ll++) 30 | { 31 | ffi_call(&cif, FFI_FN(return_ll), &rlonglong, values); 32 | CHECK(rlonglong == ll); 33 | } 34 | 35 | for (ll = 55555555555000LL; ll < 55555555555100LL; ll++) 36 | { 37 | ffi_call(&cif, FFI_FN(return_ll), &rlonglong, values); 38 | CHECK(rlonglong == ll); 39 | } 40 | exit(0); 41 | } 42 | -------------------------------------------------------------------------------- /testsuite/libffi.call/strlen.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check strlen function call. 3 | Limitations: none. 4 | PR: none. 5 | Originator: From the original ffitest.c */ 6 | 7 | /* { dg-do run } */ 8 | #include "ffitest.h" 9 | 10 | static size_t ABI_ATTR my_strlen(char *s) 11 | { 12 | return (strlen(s)); 13 | } 14 | 15 | int main (void) 16 | { 17 | ffi_cif cif; 18 | ffi_type *args[MAX_ARGS]; 19 | void *values[MAX_ARGS]; 20 | ffi_arg rint; 21 | char *s; 22 | 23 | args[0] = &ffi_type_pointer; 24 | values[0] = (void*) &s; 25 | 26 | /* Initialize the cif */ 27 | CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, 28 | &ffi_type_sint, args) == FFI_OK); 29 | 30 | s = "a"; 31 | ffi_call(&cif, FFI_FN(my_strlen), &rint, values); 32 | CHECK(rint == 1); 33 | 34 | s = "1234567"; 35 | ffi_call(&cif, FFI_FN(my_strlen), &rint, values); 36 | CHECK(rint == 7); 37 | 38 | s = "1234567890123456789012345"; 39 | ffi_call(&cif, FFI_FN(my_strlen), &rint, values); 40 | CHECK(rint == 25); 41 | 42 | exit (0); 43 | } 44 | 45 | -------------------------------------------------------------------------------- /testsuite/libffi.call/return_fl3.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check return value float. 3 | Limitations: none. 4 | PR: none. 5 | Originator: 20050212 */ 6 | 7 | /* { dg-do run } */ 8 | #include "ffitest.h" 9 | 10 | static float return_fl(float fl1, float fl2, unsigned int in3, float fl4) 11 | { 12 | return fl1 + fl2 + in3 + fl4; 13 | } 14 | int main (void) 15 | { 16 | ffi_cif cif; 17 | ffi_type *args[MAX_ARGS]; 18 | void *values[MAX_ARGS]; 19 | float fl1, fl2, fl4, rfl; 20 | unsigned int in3; 21 | args[0] = &ffi_type_float; 22 | args[1] = &ffi_type_float; 23 | args[2] = &ffi_type_uint; 24 | args[3] = &ffi_type_float; 25 | values[0] = &fl1; 26 | values[1] = &fl2; 27 | values[2] = &in3; 28 | values[3] = &fl4; 29 | 30 | /* Initialize the cif */ 31 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, 32 | &ffi_type_float, args) == FFI_OK); 33 | fl1 = 127.0; 34 | fl2 = 128.0; 35 | in3 = 255; 36 | fl4 = 512.7; 37 | 38 | ffi_call(&cif, FFI_FN(return_fl), &rfl, values); 39 | printf ("%f vs %f\n", rfl, return_fl(fl1, fl2, in3, fl4)); 40 | CHECK(rfl == fl1 + fl2 + in3 + fl4); 41 | exit(0); 42 | } 43 | -------------------------------------------------------------------------------- /testsuite/libffi.call/negint.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check that negative integers are passed correctly. 3 | Limitations: none. 4 | PR: none. 5 | Originator: From the original ffitest.c */ 6 | 7 | /* { dg-do run } */ 8 | 9 | #include "ffitest.h" 10 | 11 | static int checking(int a, short b, signed char c) 12 | { 13 | 14 | return (a < 0 && b < 0 && c < 0); 15 | } 16 | 17 | int main (void) 18 | { 19 | ffi_cif cif; 20 | ffi_type *args[MAX_ARGS]; 21 | void *values[MAX_ARGS]; 22 | ffi_arg rint; 23 | 24 | signed int si; 25 | signed short ss; 26 | signed char sc; 27 | 28 | args[0] = &ffi_type_sint; 29 | values[0] = &si; 30 | args[1] = &ffi_type_sshort; 31 | values[1] = &ss; 32 | args[2] = &ffi_type_schar; 33 | values[2] = ≻ 34 | 35 | /* Initialize the cif */ 36 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, 37 | &ffi_type_sint, args) == FFI_OK); 38 | 39 | si = -6; 40 | ss = -12; 41 | sc = -1; 42 | 43 | checking (si, ss, sc); 44 | 45 | ffi_call(&cif, FFI_FN(checking), &rint, values); 46 | 47 | printf ("%d vs %d\n", (int)rint, checking (si, ss, sc)); 48 | 49 | CHECK(rint != 0); 50 | 51 | exit (0); 52 | } 53 | -------------------------------------------------------------------------------- /testsuite/libffi.complex/return_complex1.inc: -------------------------------------------------------------------------------- 1 | /* -*-c-*- */ 2 | #include "ffitest.h" 3 | #include 4 | 5 | static _Complex T_C_TYPE return_c(_Complex T_C_TYPE c1, float fl2, unsigned int in3, _Complex T_C_TYPE c4) 6 | { 7 | return c1 + fl2 + in3 + c4; 8 | } 9 | int main (void) 10 | { 11 | ffi_cif cif; 12 | ffi_type *args[MAX_ARGS]; 13 | void *values[MAX_ARGS]; 14 | _Complex T_C_TYPE c1, c4, rc, rc2; 15 | float fl2; 16 | unsigned int in3; 17 | args[0] = &T_FFI_TYPE; 18 | args[1] = &ffi_type_float; 19 | args[2] = &ffi_type_uint; 20 | args[3] = &T_FFI_TYPE; 21 | values[0] = &c1; 22 | values[1] = &fl2; 23 | values[2] = &in3; 24 | values[3] = &c4; 25 | 26 | /* Initialize the cif */ 27 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, 28 | &T_FFI_TYPE, args) == FFI_OK); 29 | c1 = 127.0 + 255.0 * I; 30 | fl2 = 128.0; 31 | in3 = 255; 32 | c4 = 512.7 + 1024.1 * I; 33 | 34 | ffi_call(&cif, FFI_FN(return_c), &rc, values); 35 | rc2 = return_c(c1, fl2, in3, c4); 36 | printf ("%f,%fi vs %f,%fi\n", 37 | T_CONV creal (rc), T_CONV cimag (rc), 38 | T_CONV creal (rc2), T_CONV cimag (rc2)); 39 | CHECK(rc == rc2); 40 | exit(0); 41 | } 42 | -------------------------------------------------------------------------------- /winlibs.mak: -------------------------------------------------------------------------------- 1 | !IFNDEF VERSION 2 | VERSION=unknown 3 | !ENDIF 4 | 5 | !IF "$(PHP_SDK_ARCH)" == "x64" 6 | PLATFORM=x64 7 | SUBFOLDER=x64 8 | !ELSE 9 | PLATFORM=Win32 10 | SUBFOLDER= 11 | !ENDIF 12 | 13 | OUTPUT=$(MAKEDIR)\..\libffi-$(VERSION)-$(PHP_SDK_VS)-$(PHP_SDK_ARCH) 14 | ARCHIVE=$(OUTPUT).zip 15 | 16 | all: 17 | git checkout . 18 | git clean -fdx 19 | 20 | cd win32\$(PHP_SDK_VS)_$(PHP_SDK_ARCH) 21 | msbuild libffi-msvc.sln /p:Configuration=Release /p:Platform=$(PLATFORM) 22 | 23 | cd ..\.. 24 | -rmdir /s /q $(OUTPUT) 25 | xcopy include\ffi.h $(OUTPUT)\include\* 26 | # sed -i "s/#if defined _MSC_VER && !defined FFI_BUILDING/#if 0 \/*defined _MSC_VER \&\& !defined FFI_BUILDING*\//" $(OUTPUT)\include\ffi.h 27 | sed -i "s/#define LIBFFI_H/#define LIBFFI_H\n#define FFI_BUILDING/" $(OUTPUT)\include\ffi.h 28 | xcopy src\x86\ffitarget.h $(OUTPUT)\include\* 29 | xcopy fficonfig.h $(OUTPUT)\include\* 30 | xcopy win32\$(PHP_SDK_VS)_$(PHP_SDK_ARCH)\$(SUBFOLDER)\Release\libffi.lib $(OUTPUT)\lib\* 31 | xcopy win32\$(PHP_SDK_VS)_$(PHP_SDK_ARCH)\libffi\$(SUBFOLDER)\Release\libffi.pdb $(OUTPUT)\lib\* 32 | 33 | del $(ARCHIVE) 34 | 7za a $(ARCHIVE) $(OUTPUT)\* 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | libffi - Copyright (c) 1996-2019 Anthony Green, Red Hat, Inc and others. 2 | See source files for details. 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining 5 | a copy of this software and associated documentation files (the 6 | ``Software''), to deal in the Software without restriction, including 7 | without limitation the rights to use, copy, modify, merge, publish, 8 | distribute, sublicense, and/or sell copies of the Software, and to 9 | permit persons to whom the Software is furnished to do so, subject to 10 | the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 19 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 20 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 21 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /testsuite/libffi.call/return_dbl2.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check return value double. 3 | Limitations: none. 4 | PR: none. 5 | Originator: 20050212 */ 6 | 7 | /* { dg-do run } */ 8 | #include "ffitest.h" 9 | 10 | static double return_dbl(double dbl1, double dbl2, unsigned int in3, double dbl4) 11 | { 12 | return dbl1 + dbl2 + in3 + dbl4; 13 | } 14 | int main (void) 15 | { 16 | ffi_cif cif; 17 | ffi_type *args[MAX_ARGS]; 18 | void *values[MAX_ARGS]; 19 | double dbl1, dbl2, dbl4, rdbl; 20 | unsigned int in3; 21 | args[0] = &ffi_type_double; 22 | args[1] = &ffi_type_double; 23 | args[2] = &ffi_type_uint; 24 | args[3] = &ffi_type_double; 25 | values[0] = &dbl1; 26 | values[1] = &dbl2; 27 | values[2] = &in3; 28 | values[3] = &dbl4; 29 | 30 | /* Initialize the cif */ 31 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, 32 | &ffi_type_double, args) == FFI_OK); 33 | dbl1 = 127.0; 34 | dbl2 = 128.0; 35 | in3 = 255; 36 | dbl4 = 512.7; 37 | 38 | ffi_call(&cif, FFI_FN(return_dbl), &rdbl, values); 39 | printf ("%f vs %f\n", rdbl, return_dbl(dbl1, dbl2, in3, dbl4)); 40 | CHECK(rdbl == dbl1 + dbl2 + in3 + dbl4); 41 | exit(0); 42 | } 43 | -------------------------------------------------------------------------------- /libtool-version: -------------------------------------------------------------------------------- 1 | # This file is used to maintain libtool version info for libffi. See 2 | # the libtool manual to understand the meaning of the fields. This is 3 | # a separate file so that version updates don't involve re-running 4 | # automake. 5 | # 6 | # Here are a set of rules to help you update your library version 7 | # information: 8 | # 9 | # 1. Start with version information of `0:0:0' for each libtool library. 10 | # 11 | # 2. Update the version information only immediately before a public 12 | # release of your software. More frequent updates are unnecessary, 13 | # and only guarantee that the current interface number gets larger 14 | # faster. 15 | # 16 | # 3. If the library source code has changed at all since the last 17 | # update, then increment revision (`c:r:a' becomes `c:r+1:a'). 18 | # 19 | # 4. If any interfaces have been added, removed, or changed since the 20 | # last update, increment current, and set revision to 0. 21 | # 22 | # 5. If any interfaces have been added since the last public release, 23 | # then increment age. 24 | # 25 | # 6. If any interfaces have been removed since the last public 26 | # release, then set age to 0. 27 | # 28 | # CURRENT:REVISION:AGE 29 | 8:0:1 30 | -------------------------------------------------------------------------------- /testsuite/libffi.call/align_mixed.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check for proper argument alignment. 3 | Limitations: none. 4 | PR: none. 5 | Originator: (from many_win32.c) */ 6 | 7 | /* { dg-do run } */ 8 | 9 | #include "ffitest.h" 10 | 11 | static float ABI_ATTR align_arguments(int i1, 12 | double f2, 13 | int i3, 14 | double f4) 15 | { 16 | return i1+f2+i3+f4; 17 | } 18 | 19 | int main(void) 20 | { 21 | ffi_cif cif; 22 | ffi_type *args[4] = { 23 | &ffi_type_sint, 24 | &ffi_type_double, 25 | &ffi_type_sint, 26 | &ffi_type_double 27 | }; 28 | double fa[2] = {1,2}; 29 | int ia[2] = {1,2}; 30 | void *values[4] = {&ia[0], &fa[0], &ia[1], &fa[1]}; 31 | float f, ff; 32 | 33 | /* Initialize the cif */ 34 | CHECK(ffi_prep_cif(&cif, ABI_NUM, 4, 35 | &ffi_type_float, args) == FFI_OK); 36 | 37 | ff = align_arguments(ia[0], fa[0], ia[1], fa[1]); 38 | 39 | ffi_call(&cif, FFI_FN(align_arguments), &f, values); 40 | 41 | if (f == ff) 42 | printf("align arguments tests ok!\n"); 43 | else 44 | CHECK(0); 45 | exit(0); 46 | } 47 | -------------------------------------------------------------------------------- /testsuite/libffi.call/return_dbl1.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check return value double. 3 | Limitations: none. 4 | PR: none. 5 | Originator: 20050212 */ 6 | 7 | /* { dg-do run } */ 8 | #include "ffitest.h" 9 | 10 | static double return_dbl(double dbl1, float fl2, unsigned int in3, double dbl4) 11 | { 12 | return dbl1 + fl2 + in3 + dbl4; 13 | } 14 | int main (void) 15 | { 16 | ffi_cif cif; 17 | ffi_type *args[MAX_ARGS]; 18 | void *values[MAX_ARGS]; 19 | double dbl1, dbl4, rdbl; 20 | float fl2; 21 | unsigned int in3; 22 | args[0] = &ffi_type_double; 23 | args[1] = &ffi_type_float; 24 | args[2] = &ffi_type_uint; 25 | args[3] = &ffi_type_double; 26 | values[0] = &dbl1; 27 | values[1] = &fl2; 28 | values[2] = &in3; 29 | values[3] = &dbl4; 30 | 31 | /* Initialize the cif */ 32 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, 33 | &ffi_type_double, args) == FFI_OK); 34 | dbl1 = 127.0; 35 | fl2 = 128.0; 36 | in3 = 255; 37 | dbl4 = 512.7; 38 | 39 | ffi_call(&cif, FFI_FN(return_dbl), &rdbl, values); 40 | printf ("%f vs %f\n", rdbl, return_dbl(dbl1, fl2, in3, dbl4)); 41 | CHECK(rdbl == dbl1 + fl2 + in3 + dbl4); 42 | exit(0); 43 | } 44 | -------------------------------------------------------------------------------- /testsuite/libffi.call/align_stdcall.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check for proper argument alignment. 3 | Limitations: none. 4 | PR: none. 5 | Originator: (from many_win32.c) */ 6 | 7 | /* { dg-do run } */ 8 | 9 | #include "ffitest.h" 10 | 11 | static float ABI_ATTR align_arguments(int i1, 12 | double f2, 13 | int i3, 14 | double f4) 15 | { 16 | return i1+f2+i3+f4; 17 | } 18 | 19 | int main(void) 20 | { 21 | ffi_cif cif; 22 | ffi_type *args[4] = { 23 | &ffi_type_sint, 24 | &ffi_type_double, 25 | &ffi_type_sint, 26 | &ffi_type_double 27 | }; 28 | double fa[2] = {1,2}; 29 | int ia[2] = {1,2}; 30 | void *values[4] = {&ia[0], &fa[0], &ia[1], &fa[1]}; 31 | float f, ff; 32 | 33 | /* Initialize the cif */ 34 | CHECK(ffi_prep_cif(&cif, ABI_NUM, 4, 35 | &ffi_type_float, args) == FFI_OK); 36 | 37 | ff = align_arguments(ia[0], fa[0], ia[1], fa[1]);; 38 | 39 | ffi_call(&cif, FFI_FN(align_arguments), &f, values); 40 | 41 | if (f == ff) 42 | printf("align arguments tests ok!\n"); 43 | else 44 | CHECK(0); 45 | exit(0); 46 | } 47 | -------------------------------------------------------------------------------- /testsuite/libffi.go/go.exp: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2003, 2006, 2009, 2010, 2014 Free Software Foundation, Inc. 2 | 3 | # This program is free software; you can redistribute it and/or modify 4 | # it under the terms of the GNU General Public License as published by 5 | # the Free Software Foundation; either version 3 of the License, or 6 | # (at your option) any later version. 7 | # 8 | # This program is distributed in the hope that it will be useful, 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | # GNU General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License 14 | # along with this program; see the file COPYING3. If not see 15 | # . 16 | 17 | dg-init 18 | libffi-init 19 | 20 | global srcdir subdir 21 | 22 | set tlist [lsort [glob -nocomplain -- $srcdir/$subdir/*.{c,cc}]] 23 | 24 | if { [libffi_feature_test "#ifdef FFI_GO_CLOSURES"] } { 25 | run-many-tests $tlist "" 26 | } else { 27 | foreach test $tlist { 28 | unsupported "$test" 29 | } 30 | } 31 | 32 | dg-finish 33 | 34 | # Local Variables: 35 | # tcl-indent-level:4 36 | # End: 37 | -------------------------------------------------------------------------------- /testsuite/libffi.call/strlen2.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check strlen function call with additional arguments. 3 | Limitations: none. 4 | PR: none. 5 | Originator: From the original ffitest.c */ 6 | 7 | /* { dg-do run } */ 8 | 9 | #include "ffitest.h" 10 | 11 | static size_t ABI_ATTR my_f(char *s, float a) 12 | { 13 | return (size_t) ((int) strlen(s) + (int) a); 14 | } 15 | 16 | int main (void) 17 | { 18 | ffi_cif cif; 19 | ffi_type *args[MAX_ARGS]; 20 | void *values[MAX_ARGS]; 21 | ffi_arg rint; 22 | char *s; 23 | float v2; 24 | args[0] = &ffi_type_pointer; 25 | args[1] = &ffi_type_float; 26 | values[0] = (void*) &s; 27 | values[1] = (void*) &v2; 28 | 29 | /* Initialize the cif */ 30 | CHECK(ffi_prep_cif(&cif, ABI_NUM, 2, 31 | &ffi_type_sint, args) == FFI_OK); 32 | 33 | s = "a"; 34 | v2 = 0.0; 35 | ffi_call(&cif, FFI_FN(my_f), &rint, values); 36 | CHECK(rint == 1); 37 | 38 | s = "1234567"; 39 | v2 = -1.0; 40 | ffi_call(&cif, FFI_FN(my_f), &rint, values); 41 | CHECK(rint == 6); 42 | 43 | s = "1234567890123456789012345"; 44 | v2 = 1.0; 45 | ffi_call(&cif, FFI_FN(my_f), &rint, values); 46 | CHECK(rint == 26); 47 | 48 | exit(0); 49 | } 50 | -------------------------------------------------------------------------------- /testsuite/libffi.call/strlen3.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check strlen function call with additional arguments. 3 | Limitations: none. 4 | PR: none. 5 | Originator: From the original ffitest.c */ 6 | 7 | /* { dg-do run } */ 8 | 9 | #include "ffitest.h" 10 | 11 | static size_t ABI_ATTR my_f(float a, char *s) 12 | { 13 | return (size_t) ((int) strlen(s) + (int) a); 14 | } 15 | 16 | int main (void) 17 | { 18 | ffi_cif cif; 19 | ffi_type *args[MAX_ARGS]; 20 | void *values[MAX_ARGS]; 21 | ffi_arg rint; 22 | char *s; 23 | float v2; 24 | args[1] = &ffi_type_pointer; 25 | args[0] = &ffi_type_float; 26 | values[1] = (void*) &s; 27 | values[0] = (void*) &v2; 28 | 29 | /* Initialize the cif */ 30 | CHECK(ffi_prep_cif(&cif, ABI_NUM, 2, 31 | &ffi_type_sint, args) == FFI_OK); 32 | 33 | s = "a"; 34 | v2 = 0.0; 35 | ffi_call(&cif, FFI_FN(my_f), &rint, values); 36 | CHECK(rint == 1); 37 | 38 | s = "1234567"; 39 | v2 = -1.0; 40 | ffi_call(&cif, FFI_FN(my_f), &rint, values); 41 | CHECK(rint == 6); 42 | 43 | s = "1234567890123456789012345"; 44 | v2 = 1.0; 45 | ffi_call(&cif, FFI_FN(my_f), &rint, values); 46 | CHECK(rint == 26); 47 | 48 | exit(0); 49 | } 50 | -------------------------------------------------------------------------------- /testsuite/libffi.complex/return_complex2.inc: -------------------------------------------------------------------------------- 1 | /* -*-c-*- */ 2 | #include "ffitest.h" 3 | #include 4 | 5 | _Complex T_C_TYPE 6 | return_c(_Complex T_C_TYPE c1, _Complex T_C_TYPE c2, 7 | unsigned int in3, _Complex T_C_TYPE c4) 8 | { 9 | volatile _Complex T_C_TYPE r = c1 + c2 + in3 + c4; 10 | return r; 11 | } 12 | 13 | int main (void) 14 | { 15 | ffi_cif cif; 16 | ffi_type *args[MAX_ARGS]; 17 | void *values[MAX_ARGS]; 18 | _Complex T_C_TYPE c1, c2, c4, rc, rc2; 19 | unsigned int in3; 20 | args[0] = &T_FFI_TYPE; 21 | args[1] = &T_FFI_TYPE; 22 | args[2] = &ffi_type_uint; 23 | args[3] = &T_FFI_TYPE; 24 | values[0] = &c1; 25 | values[1] = &c2; 26 | values[2] = &in3; 27 | values[3] = &c4; 28 | 29 | /* Initialize the cif */ 30 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, 31 | &T_FFI_TYPE, args) == FFI_OK); 32 | c1 = 127.0 + 255.0 * I; 33 | c2 = 128.0 + 256.0; 34 | in3 = 255; 35 | c4 = 512.7 + 1024.1 * I; 36 | 37 | ffi_call(&cif, FFI_FN(return_c), &rc, values); 38 | rc2 = return_c(c1, c2, in3, c4); 39 | printf ("%f,%fi vs %f,%fi\n", 40 | T_CONV creal (rc), T_CONV cimag (rc), 41 | T_CONV creal (rc2), T_CONV cimag (rc2)); 42 | CHECK(rc == rc2); 43 | exit(0); 44 | } 45 | -------------------------------------------------------------------------------- /testsuite/libffi.complex/complex.exp: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2003, 2006, 2009, 2010, 2014 Free Software Foundation, Inc. 2 | 3 | # This program is free software; you can redistribute it and/or modify 4 | # it under the terms of the GNU General Public License as published by 5 | # the Free Software Foundation; either version 3 of the License, or 6 | # (at your option) any later version. 7 | # 8 | # This program is distributed in the hope that it will be useful, 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | # GNU General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License 14 | # along with this program; see the file COPYING3. If not see 15 | # . 16 | 17 | dg-init 18 | libffi-init 19 | 20 | global srcdir subdir 21 | 22 | set tlist [lsort [glob -nocomplain -- $srcdir/$subdir/*.{c,cc}]] 23 | 24 | if { [libffi_feature_test "#ifdef FFI_TARGET_HAS_COMPLEX_TYPE"] } { 25 | run-many-tests $tlist "" 26 | } else { 27 | foreach test $tlist { 28 | unsupported "$test" 29 | } 30 | } 31 | 32 | dg-finish 33 | 34 | # Local Variables: 35 | # tcl-indent-level:4 36 | # End: 37 | -------------------------------------------------------------------------------- /testsuite/libffi.call/return_ll1.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check if long long are passed in the corresponding regs on ppc. 3 | Limitations: none. 4 | PR: 20104. 5 | Originator: 20050222 */ 6 | 7 | /* { dg-do run } */ 8 | /* { dg-options "-Wno-format" { target alpha*-dec-osf* } } */ 9 | #include "ffitest.h" 10 | static long long return_ll(int ll0, long long ll1, int ll2) 11 | { 12 | return ll0 + ll1 + ll2; 13 | } 14 | 15 | int main (void) 16 | { 17 | ffi_cif cif; 18 | ffi_type *args[MAX_ARGS]; 19 | void *values[MAX_ARGS]; 20 | long long rlonglong; 21 | long long ll1; 22 | unsigned ll0, ll2; 23 | 24 | args[0] = &ffi_type_sint; 25 | args[1] = &ffi_type_sint64; 26 | args[2] = &ffi_type_sint; 27 | values[0] = &ll0; 28 | values[1] = &ll1; 29 | values[2] = &ll2; 30 | 31 | /* Initialize the cif */ 32 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, 33 | &ffi_type_sint64, args) == FFI_OK); 34 | 35 | ll0 = 11111111; 36 | ll1 = 11111111111000LL; 37 | ll2 = 11111111; 38 | 39 | ffi_call(&cif, FFI_FN(return_ll), &rlonglong, values); 40 | printf("res: %" PRIdLL ", %" PRIdLL "\n", rlonglong, ll0 + ll1 + ll2); 41 | /* { dg-output "res: 11111133333222, 11111133333222" } */ 42 | exit(0); 43 | } 44 | -------------------------------------------------------------------------------- /testsuite/libffi.closures/cls_sint.c: -------------------------------------------------------------------------------- 1 | /* Area: closure_call 2 | Purpose: Check return value sint32. 3 | Limitations: none. 4 | PR: none. 5 | Originator: 20031108 */ 6 | 7 | /* { dg-do run } */ 8 | #include "ffitest.h" 9 | 10 | static void cls_ret_sint_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, 11 | void* userdata __UNUSED__) 12 | { 13 | *(ffi_arg*)resp = *(signed int *)args[0]; 14 | printf("%d: %d\n",*(signed int *)args[0], 15 | (int)*(ffi_arg *)(resp)); 16 | } 17 | typedef signed int (*cls_ret_sint)(signed int); 18 | 19 | int main (void) 20 | { 21 | ffi_cif cif; 22 | void *code; 23 | ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); 24 | ffi_type * cl_arg_types[2]; 25 | signed int res; 26 | 27 | cl_arg_types[0] = &ffi_type_sint; 28 | cl_arg_types[1] = NULL; 29 | 30 | /* Initialize the cif */ 31 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 32 | &ffi_type_sint, cl_arg_types) == FFI_OK); 33 | 34 | CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_sint_fn, NULL, code) == FFI_OK); 35 | 36 | res = (*((cls_ret_sint)code))(65534); 37 | /* { dg-output "65534: 65534" } */ 38 | printf("res: %d\n",res); 39 | /* { dg-output "\nres: 65534" } */ 40 | 41 | exit(0); 42 | } 43 | -------------------------------------------------------------------------------- /testsuite/libffi.closures/cls_float.c: -------------------------------------------------------------------------------- 1 | /* Area: closure_call 2 | Purpose: Check return value float. 3 | Limitations: none. 4 | PR: none. 5 | Originator: 20030828 */ 6 | 7 | /* { dg-do run } */ 8 | #include "ffitest.h" 9 | 10 | static void cls_ret_float_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, 11 | void* userdata __UNUSED__) 12 | { 13 | *(float *)resp = *(float *)args[0]; 14 | 15 | printf("%g: %g\n",*(float *)args[0], 16 | *(float *)resp); 17 | } 18 | 19 | typedef float (*cls_ret_float)(float); 20 | 21 | int main (void) 22 | { 23 | ffi_cif cif; 24 | void *code; 25 | ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); 26 | ffi_type * cl_arg_types[2]; 27 | float res; 28 | 29 | cl_arg_types[0] = &ffi_type_float; 30 | cl_arg_types[1] = NULL; 31 | 32 | /* Initialize the cif */ 33 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 34 | &ffi_type_float, cl_arg_types) == FFI_OK); 35 | 36 | CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_float_fn, NULL, code) == FFI_OK); 37 | res = ((((cls_ret_float)code)(-2122.12))); 38 | /* { dg-output "\\-2122.12: \\-2122.12" } */ 39 | printf("res: %.6f\n", res); 40 | /* { dg-output "\nres: \-2122.120117" } */ 41 | exit(0); 42 | } 43 | -------------------------------------------------------------------------------- /testsuite/libffi.closures/cls_uchar.c: -------------------------------------------------------------------------------- 1 | /* Area: closure_call 2 | Purpose: Check return value uchar. 3 | Limitations: none. 4 | PR: none. 5 | Originator: 20030828 */ 6 | 7 | /* { dg-do run } */ 8 | #include "ffitest.h" 9 | 10 | static void cls_ret_uchar_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, 11 | void* userdata __UNUSED__) 12 | { 13 | *(ffi_arg*)resp = *(unsigned char *)args[0]; 14 | printf("%d: %d\n",*(unsigned char *)args[0], 15 | (int)*(ffi_arg *)(resp)); 16 | } 17 | typedef unsigned char (*cls_ret_uchar)(unsigned char); 18 | 19 | int main (void) 20 | { 21 | ffi_cif cif; 22 | void *code; 23 | ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); 24 | ffi_type * cl_arg_types[2]; 25 | unsigned char res; 26 | 27 | cl_arg_types[0] = &ffi_type_uchar; 28 | cl_arg_types[1] = NULL; 29 | 30 | /* Initialize the cif */ 31 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 32 | &ffi_type_uchar, cl_arg_types) == FFI_OK); 33 | 34 | CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_uchar_fn, NULL, code) == FFI_OK); 35 | 36 | res = (*((cls_ret_uchar)code))(127); 37 | /* { dg-output "127: 127" } */ 38 | printf("res: %d\n",res); 39 | /* { dg-output "\nres: 127" } */ 40 | 41 | exit(0); 42 | } 43 | -------------------------------------------------------------------------------- /testsuite/libffi.closures/cls_schar.c: -------------------------------------------------------------------------------- 1 | /* Area: closure_call 2 | Purpose: Check return value schar. 3 | Limitations: none. 4 | PR: none. 5 | Originator: 20031108 */ 6 | 7 | 8 | 9 | /* { dg-do run } */ 10 | #include "ffitest.h" 11 | 12 | static void cls_ret_schar_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, 13 | void* userdata __UNUSED__) 14 | { 15 | *(ffi_arg*)resp = *(signed char *)args[0]; 16 | printf("%d: %d\n",*(signed char *)args[0], 17 | (int)*(ffi_arg *)(resp)); 18 | } 19 | typedef signed char (*cls_ret_schar)(signed char); 20 | 21 | int main (void) 22 | { 23 | ffi_cif cif; 24 | void *code; 25 | ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); 26 | ffi_type * cl_arg_types[2]; 27 | signed char res; 28 | 29 | cl_arg_types[0] = &ffi_type_schar; 30 | cl_arg_types[1] = NULL; 31 | 32 | /* Initialize the cif */ 33 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 34 | &ffi_type_schar, cl_arg_types) == FFI_OK); 35 | 36 | CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_schar_fn, NULL, code) == FFI_OK); 37 | 38 | res = (*((cls_ret_schar)code))(127); 39 | /* { dg-output "127: 127" } */ 40 | printf("res: %d\n", res); 41 | /* { dg-output "\nres: 127" } */ 42 | 43 | exit(0); 44 | } 45 | -------------------------------------------------------------------------------- /testsuite/libffi.closures/cls_sshort.c: -------------------------------------------------------------------------------- 1 | /* Area: closure_call 2 | Purpose: Check return value sshort. 3 | Limitations: none. 4 | PR: none. 5 | Originator: 20031108 */ 6 | 7 | /* { dg-do run } */ 8 | #include "ffitest.h" 9 | 10 | static void cls_ret_sshort_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, 11 | void* userdata __UNUSED__) 12 | { 13 | *(ffi_arg*)resp = *(signed short *)args[0]; 14 | printf("%d: %d\n",*(signed short *)args[0], 15 | (int)*(ffi_arg *)(resp)); 16 | } 17 | typedef signed short (*cls_ret_sshort)(signed short); 18 | 19 | int main (void) 20 | { 21 | ffi_cif cif; 22 | void *code; 23 | ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); 24 | ffi_type * cl_arg_types[2]; 25 | signed short res; 26 | 27 | cl_arg_types[0] = &ffi_type_sshort; 28 | cl_arg_types[1] = NULL; 29 | 30 | /* Initialize the cif */ 31 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 32 | &ffi_type_sshort, cl_arg_types) == FFI_OK); 33 | 34 | CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_sshort_fn, NULL, code) == FFI_OK); 35 | 36 | res = (*((cls_ret_sshort)code))(255); 37 | /* { dg-output "255: 255" } */ 38 | printf("res: %d\n",res); 39 | /* { dg-output "\nres: 255" } */ 40 | 41 | exit(0); 42 | } 43 | -------------------------------------------------------------------------------- /testsuite/libffi.closures/cls_ulong_va.c: -------------------------------------------------------------------------------- 1 | /* Area: closure_call 2 | Purpose: Test anonymous unsigned long argument. 3 | Limitations: none. 4 | PR: none. 5 | Originator: ARM Ltd. */ 6 | 7 | /* { dg-do run } */ 8 | 9 | #include "ffitest.h" 10 | 11 | typedef unsigned long T; 12 | 13 | static void cls_ret_T_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, 14 | void* userdata __UNUSED__) 15 | { 16 | *(T *)resp = *(T *)args[0]; 17 | 18 | printf("%ld: %ld %ld\n", *(T *)resp, *(T *)args[0], *(T *)args[1]); 19 | } 20 | 21 | typedef T (*cls_ret_T)(T, ...); 22 | 23 | int main (void) 24 | { 25 | ffi_cif cif; 26 | void *code; 27 | ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); 28 | ffi_type * cl_arg_types[3]; 29 | T res; 30 | 31 | cl_arg_types[0] = &ffi_type_ulong; 32 | cl_arg_types[1] = &ffi_type_ulong; 33 | cl_arg_types[2] = NULL; 34 | 35 | /* Initialize the cif */ 36 | CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2, 37 | &ffi_type_ulong, cl_arg_types) == FFI_OK); 38 | 39 | CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_T_fn, NULL, code) == FFI_OK); 40 | res = ((((cls_ret_T)code)(67, 4))); 41 | /* { dg-output "67: 67 4" } */ 42 | printf("res: %ld\n", res); 43 | /* { dg-output "\nres: 67" } */ 44 | exit(0); 45 | } 46 | -------------------------------------------------------------------------------- /testsuite/libffi.closures/cls_double.c: -------------------------------------------------------------------------------- 1 | /* Area: closure_call 2 | Purpose: Check return value double. 3 | Limitations: none. 4 | PR: none. 5 | Originator: 20030828 */ 6 | 7 | /* { dg-do run } */ 8 | #include "ffitest.h" 9 | 10 | static void cls_ret_double_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, 11 | void* userdata __UNUSED__) 12 | { 13 | *(double *)resp = *(double *)args[0]; 14 | 15 | printf("%f: %f\n",*(double *)args[0], 16 | *(double *)resp); 17 | } 18 | typedef double (*cls_ret_double)(double); 19 | 20 | int main (void) 21 | { 22 | ffi_cif cif; 23 | void *code; 24 | ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); 25 | ffi_type * cl_arg_types[2]; 26 | double res; 27 | 28 | cl_arg_types[0] = &ffi_type_double; 29 | cl_arg_types[1] = NULL; 30 | 31 | /* Initialize the cif */ 32 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 33 | &ffi_type_double, cl_arg_types) == FFI_OK); 34 | 35 | CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_double_fn, NULL, code) == FFI_OK); 36 | 37 | res = (*((cls_ret_double)code))(21474.789); 38 | /* { dg-output "21474.789000: 21474.789000" } */ 39 | printf("res: %.6f\n", res); 40 | /* { dg-output "\nres: 21474.789000" } */ 41 | 42 | exit(0); 43 | } 44 | -------------------------------------------------------------------------------- /testsuite/libffi.closures/cls_uchar_va.c: -------------------------------------------------------------------------------- 1 | /* Area: closure_call 2 | Purpose: Test anonymous unsigned char argument. 3 | Limitations: none. 4 | PR: none. 5 | Originator: ARM Ltd. */ 6 | 7 | /* { dg-do run } */ 8 | #include "ffitest.h" 9 | 10 | typedef unsigned char T; 11 | 12 | static void cls_ret_T_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, 13 | void* userdata __UNUSED__) 14 | { 15 | *(ffi_arg *)resp = *(T *)args[0]; 16 | 17 | printf("%d: %d %d\n", (int)(*(ffi_arg *)resp), *(T *)args[0], *(T *)args[1]); 18 | } 19 | 20 | typedef T (*cls_ret_T)(T, ...); 21 | 22 | int main (void) 23 | { 24 | ffi_cif cif; 25 | void *code; 26 | ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); 27 | ffi_type * cl_arg_types[3]; 28 | T res; 29 | 30 | cl_arg_types[0] = &ffi_type_uchar; 31 | cl_arg_types[1] = &ffi_type_uchar; 32 | cl_arg_types[2] = NULL; 33 | 34 | /* Initialize the cif */ 35 | CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2, 36 | &ffi_type_uchar, cl_arg_types) == FFI_OK); 37 | 38 | CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_T_fn, NULL, code) == FFI_OK); 39 | res = ((((cls_ret_T)code)(67, 4))); 40 | /* { dg-output "67: 67 4" } */ 41 | printf("res: %d\n", res); 42 | /* { dg-output "\nres: 67" } */ 43 | exit(0); 44 | } 45 | -------------------------------------------------------------------------------- /testsuite/libffi.closures/cls_uint.c: -------------------------------------------------------------------------------- 1 | /* Area: closure_call 2 | Purpose: Check return value uint. 3 | Limitations: none. 4 | PR: none. 5 | Originator: 20030828 */ 6 | 7 | /* { dg-do run } */ 8 | #include "ffitest.h" 9 | 10 | static void cls_ret_uint_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, 11 | void* userdata __UNUSED__) 12 | { 13 | *(ffi_arg *)resp = *(unsigned int *)args[0]; 14 | 15 | printf("%d: %d\n",*(unsigned int *)args[0], 16 | (int)*(ffi_arg *)(resp)); 17 | } 18 | typedef unsigned int (*cls_ret_uint)(unsigned int); 19 | 20 | int main (void) 21 | { 22 | ffi_cif cif; 23 | void *code; 24 | ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); 25 | ffi_type * cl_arg_types[2]; 26 | unsigned int res; 27 | 28 | cl_arg_types[0] = &ffi_type_uint; 29 | cl_arg_types[1] = NULL; 30 | 31 | /* Initialize the cif */ 32 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 33 | &ffi_type_uint, cl_arg_types) == FFI_OK); 34 | 35 | CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_uint_fn, NULL, code) == FFI_OK); 36 | 37 | res = (*((cls_ret_uint)code))(2147483647); 38 | /* { dg-output "2147483647: 2147483647" } */ 39 | printf("res: %d\n",res); 40 | /* { dg-output "\nres: 2147483647" } */ 41 | 42 | exit(0); 43 | } 44 | -------------------------------------------------------------------------------- /testsuite/libffi.closures/cls_uint_va.c: -------------------------------------------------------------------------------- 1 | /* Area: closure_call 2 | Purpose: Test anonymous unsigned int argument. 3 | Limitations: none. 4 | PR: none. 5 | Originator: ARM Ltd. */ 6 | 7 | /* { dg-do run } */ 8 | 9 | #include "ffitest.h" 10 | 11 | typedef unsigned int T; 12 | 13 | static void cls_ret_T_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, 14 | void* userdata __UNUSED__) 15 | { 16 | *(ffi_arg *)resp = *(T *)args[0]; 17 | 18 | printf("%d: %d %d\n", (int)*(ffi_arg *)resp, *(T *)args[0], *(T *)args[1]); 19 | } 20 | 21 | typedef T (*cls_ret_T)(T, ...); 22 | 23 | int main (void) 24 | { 25 | ffi_cif cif; 26 | void *code; 27 | ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); 28 | ffi_type * cl_arg_types[3]; 29 | T res; 30 | 31 | cl_arg_types[0] = &ffi_type_uint; 32 | cl_arg_types[1] = &ffi_type_uint; 33 | cl_arg_types[2] = NULL; 34 | 35 | /* Initialize the cif */ 36 | CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2, 37 | &ffi_type_uint, cl_arg_types) == FFI_OK); 38 | 39 | CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_T_fn, NULL, code) == FFI_OK); 40 | res = ((((cls_ret_T)code)(67, 4))); 41 | /* { dg-output "67: 67 4" } */ 42 | printf("res: %d\n", res); 43 | /* { dg-output "\nres: 67" } */ 44 | exit(0); 45 | } 46 | -------------------------------------------------------------------------------- /testsuite/libffi.closures/cls_ushort_va.c: -------------------------------------------------------------------------------- 1 | /* Area: closure_call 2 | Purpose: Test anonymous unsigned short argument. 3 | Limitations: none. 4 | PR: none. 5 | Originator: ARM Ltd. */ 6 | 7 | /* { dg-do run } */ 8 | #include "ffitest.h" 9 | 10 | typedef unsigned short T; 11 | 12 | static void cls_ret_T_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, 13 | void* userdata __UNUSED__) 14 | { 15 | *(ffi_arg *)resp = *(T *)args[0]; 16 | 17 | printf("%d: %d %d\n", (int)(*(ffi_arg *)resp), *(T *)args[0], *(T *)args[1]); 18 | } 19 | 20 | typedef T (*cls_ret_T)(T, ...); 21 | 22 | int main (void) 23 | { 24 | ffi_cif cif; 25 | void *code; 26 | ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); 27 | ffi_type * cl_arg_types[3]; 28 | T res; 29 | 30 | cl_arg_types[0] = &ffi_type_ushort; 31 | cl_arg_types[1] = &ffi_type_ushort; 32 | cl_arg_types[2] = NULL; 33 | 34 | /* Initialize the cif */ 35 | CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2, 36 | &ffi_type_ushort, cl_arg_types) == FFI_OK); 37 | 38 | CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_T_fn, NULL, code) == FFI_OK); 39 | res = ((((cls_ret_T)code)(67, 4))); 40 | /* { dg-output "67: 67 4" } */ 41 | printf("res: %d\n", res); 42 | /* { dg-output "\nres: 67" } */ 43 | exit(0); 44 | } 45 | -------------------------------------------------------------------------------- /testsuite/libffi.call/offsets.c: -------------------------------------------------------------------------------- 1 | /* Area: Struct layout 2 | Purpose: Test ffi_get_struct_offsets 3 | Limitations: none. 4 | PR: none. 5 | Originator: Tom Tromey. */ 6 | 7 | /* { dg-do run } */ 8 | #include "ffitest.h" 9 | #include 10 | 11 | struct test_1 12 | { 13 | char c; 14 | float f; 15 | char c2; 16 | int i; 17 | }; 18 | 19 | int 20 | main (void) 21 | { 22 | ffi_type test_1_type; 23 | ffi_type *test_1_elements[5]; 24 | size_t test_1_offsets[4]; 25 | 26 | test_1_elements[0] = &ffi_type_schar; 27 | test_1_elements[1] = &ffi_type_float; 28 | test_1_elements[2] = &ffi_type_schar; 29 | test_1_elements[3] = &ffi_type_sint; 30 | test_1_elements[4] = NULL; 31 | 32 | test_1_type.size = 0; 33 | test_1_type.alignment = 0; 34 | test_1_type.type = FFI_TYPE_STRUCT; 35 | test_1_type.elements = test_1_elements; 36 | 37 | CHECK (ffi_get_struct_offsets (FFI_DEFAULT_ABI, &test_1_type, test_1_offsets) 38 | == FFI_OK); 39 | CHECK (test_1_type.size == sizeof (struct test_1)); 40 | CHECK (offsetof (struct test_1, c) == test_1_offsets[0]); 41 | CHECK (offsetof (struct test_1, f) == test_1_offsets[1]); 42 | CHECK (offsetof (struct test_1, c2) == test_1_offsets[2]); 43 | CHECK (offsetof (struct test_1, i) == test_1_offsets[3]); 44 | 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /testsuite/libffi.closures/cls_ushort.c: -------------------------------------------------------------------------------- 1 | /* Area: closure_call 2 | Purpose: Check return value ushort. 3 | Limitations: none. 4 | PR: none. 5 | Originator: 20030828 */ 6 | 7 | /* { dg-do run } */ 8 | #include "ffitest.h" 9 | 10 | static void cls_ret_ushort_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, 11 | void* userdata __UNUSED__) 12 | { 13 | *(ffi_arg*)resp = *(unsigned short *)args[0]; 14 | 15 | printf("%d: %d\n",*(unsigned short *)args[0], 16 | (int)*(ffi_arg *)(resp)); 17 | } 18 | typedef unsigned short (*cls_ret_ushort)(unsigned short); 19 | 20 | int main (void) 21 | { 22 | ffi_cif cif; 23 | void *code; 24 | ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); 25 | ffi_type * cl_arg_types[2]; 26 | unsigned short res; 27 | 28 | cl_arg_types[0] = &ffi_type_ushort; 29 | cl_arg_types[1] = NULL; 30 | 31 | /* Initialize the cif */ 32 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 33 | &ffi_type_ushort, cl_arg_types) == FFI_OK); 34 | 35 | CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_ushort_fn, NULL, code) == FFI_OK); 36 | 37 | res = (*((cls_ret_ushort)code))(65535); 38 | /* { dg-output "65535: 65535" } */ 39 | printf("res: %d\n",res); 40 | /* { dg-output "\nres: 65535" } */ 41 | 42 | exit(0); 43 | } 44 | -------------------------------------------------------------------------------- /testsuite/libffi.call/struct10.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check structures. 3 | Limitations: none. 4 | PR: none. 5 | Originator: Sergei Trofimovich 6 | 7 | The test originally discovered in ruby's bindings 8 | for ffi in https://bugs.gentoo.org/634190 */ 9 | 10 | /* { dg-do run } */ 11 | #include "ffitest.h" 12 | 13 | struct s { 14 | int s32; 15 | float f32; 16 | signed char s8; 17 | }; 18 | 19 | struct s make_s(void) { 20 | struct s r; 21 | r.s32 = 0x1234; 22 | r.f32 = 7.0; 23 | r.s8 = 0x78; 24 | return r; 25 | } 26 | 27 | int main() { 28 | ffi_cif cif; 29 | struct s r; 30 | ffi_type rtype; 31 | ffi_type* s_fields[] = { 32 | &ffi_type_sint, 33 | &ffi_type_float, 34 | &ffi_type_schar, 35 | NULL, 36 | }; 37 | 38 | rtype.size = 0; 39 | rtype.alignment = 0, 40 | rtype.type = FFI_TYPE_STRUCT, 41 | rtype.elements = s_fields, 42 | 43 | r.s32 = 0xbad; 44 | r.f32 = 999.999; 45 | r.s8 = 0x51; 46 | 47 | // Here we emulate the following call: 48 | //r = make_s(); 49 | 50 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 0, &rtype, NULL) == FFI_OK); 51 | ffi_call(&cif, FFI_FN(make_s), &r, NULL); 52 | 53 | CHECK(r.s32 == 0x1234); 54 | CHECK(r.f32 == 7.0); 55 | CHECK(r.s8 == 0x78); 56 | exit(0); 57 | } 58 | -------------------------------------------------------------------------------- /testsuite/libffi.closures/unwindtest_ffi_call.cc: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call, unwind info 2 | Purpose: Check if the unwind information is passed correctly. 3 | Limitations: none. 4 | PR: none. 5 | Originator: Andreas Tobler 20061213 */ 6 | 7 | /* { dg-do run { xfail moxie*-*-* } } */ 8 | 9 | #include "ffitest.h" 10 | 11 | static int checking(int a __UNUSED__, short b __UNUSED__, 12 | signed char c __UNUSED__) 13 | { 14 | throw 9; 15 | } 16 | 17 | int main (void) 18 | { 19 | ffi_cif cif; 20 | ffi_type *args[MAX_ARGS]; 21 | void *values[MAX_ARGS]; 22 | ffi_arg rint; 23 | 24 | signed int si; 25 | signed short ss; 26 | signed char sc; 27 | 28 | args[0] = &ffi_type_sint; 29 | values[0] = &si; 30 | args[1] = &ffi_type_sshort; 31 | values[1] = &ss; 32 | args[2] = &ffi_type_schar; 33 | values[2] = ≻ 34 | 35 | /* Initialize the cif */ 36 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, 37 | &ffi_type_sint, args) == FFI_OK); 38 | 39 | si = -6; 40 | ss = -12; 41 | sc = -1; 42 | { 43 | try 44 | { 45 | ffi_call(&cif, FFI_FN(checking), &rint, values); 46 | } catch (int exception_code) 47 | { 48 | CHECK(exception_code == 9); 49 | } 50 | printf("part one OK\n"); 51 | /* { dg-output "part one OK" } */ 52 | } 53 | exit(0); 54 | } 55 | -------------------------------------------------------------------------------- /testsuite/libffi.complex/cls_complex.inc: -------------------------------------------------------------------------------- 1 | /* -*-c-*- */ 2 | #include "ffitest.h" 3 | #include 4 | 5 | static void cls_ret_complex_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, 6 | void* userdata __UNUSED__) 7 | { 8 | _Complex T_C_TYPE *pa; 9 | _Complex T_C_TYPE *pr; 10 | pa = (_Complex T_C_TYPE *)args[0]; 11 | pr = (_Complex T_C_TYPE *)resp; 12 | *pr = *pa; 13 | 14 | printf("%.6f,%.6fi: %.6f,%.6fi\n", 15 | T_CONV creal (*pa), T_CONV cimag (*pa), 16 | T_CONV creal (*pr), T_CONV cimag (*pr)); 17 | } 18 | typedef _Complex T_C_TYPE (*cls_ret_complex)(_Complex T_C_TYPE); 19 | 20 | int main (void) 21 | { 22 | ffi_cif cif; 23 | void *code; 24 | ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); 25 | ffi_type * cl_arg_types[2]; 26 | _Complex T_C_TYPE res; 27 | 28 | cl_arg_types[0] = &T_FFI_TYPE; 29 | cl_arg_types[1] = NULL; 30 | 31 | /* Initialize the cif */ 32 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 33 | &T_FFI_TYPE, cl_arg_types) == FFI_OK); 34 | 35 | CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_complex_fn, NULL, code) == FFI_OK); 36 | 37 | res = (*((cls_ret_complex)code))(0.125 + 128.0 * I); 38 | printf("res: %.6f,%.6fi\n", T_CONV creal (res), T_CONV cimag (res)); 39 | CHECK (res == (0.125 + 128.0 * I)); 40 | 41 | exit(0); 42 | } 43 | -------------------------------------------------------------------------------- /testsuite/libffi.call/return_fl2.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check return value float. 3 | Limitations: none. 4 | PR: none. 5 | Originator: 20050212 */ 6 | 7 | /* { dg-do run } */ 8 | #include "ffitest.h" 9 | 10 | /* Use volatile float to avoid false negative on ix86. See PR target/323. */ 11 | static float return_fl(float fl1, float fl2, float fl3, float fl4) 12 | { 13 | volatile float sum; 14 | 15 | sum = fl1 + fl2 + fl3 + fl4; 16 | return sum; 17 | } 18 | int main (void) 19 | { 20 | ffi_cif cif; 21 | ffi_type *args[MAX_ARGS]; 22 | void *values[MAX_ARGS]; 23 | float fl1, fl2, fl3, fl4, rfl; 24 | volatile float sum; 25 | 26 | args[0] = &ffi_type_float; 27 | args[1] = &ffi_type_float; 28 | args[2] = &ffi_type_float; 29 | args[3] = &ffi_type_float; 30 | values[0] = &fl1; 31 | values[1] = &fl2; 32 | values[2] = &fl3; 33 | values[3] = &fl4; 34 | 35 | /* Initialize the cif */ 36 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, 37 | &ffi_type_float, args) == FFI_OK); 38 | fl1 = 127.0; 39 | fl2 = 128.0; 40 | fl3 = 255.1; 41 | fl4 = 512.7; 42 | 43 | ffi_call(&cif, FFI_FN(return_fl), &rfl, values); 44 | printf ("%f vs %f\n", rfl, return_fl(fl1, fl2, fl3, fl4)); 45 | 46 | sum = fl1 + fl2 + fl3 + fl4; 47 | CHECK(rfl == sum); 48 | exit(0); 49 | } 50 | -------------------------------------------------------------------------------- /testsuite/libffi.call/many2.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check uint8_t arguments. 3 | Limitations: none. 4 | PR: PR45677. 5 | Originator: Dan Witte 20100916 */ 6 | 7 | /* { dg-do run } */ 8 | 9 | #include "ffitest.h" 10 | 11 | #define NARGS 7 12 | 13 | typedef unsigned char u8; 14 | 15 | #ifdef __GNUC__ 16 | __attribute__((noinline)) 17 | #endif 18 | uint8_t 19 | foo (uint8_t a, uint8_t b, uint8_t c, uint8_t d, 20 | uint8_t e, uint8_t f, uint8_t g) 21 | { 22 | return a + b + c + d + e + f + g; 23 | } 24 | 25 | uint8_t ABI_ATTR 26 | bar (uint8_t a, uint8_t b, uint8_t c, uint8_t d, 27 | uint8_t e, uint8_t f, uint8_t g) 28 | { 29 | return foo (a, b, c, d, e, f, g); 30 | } 31 | 32 | int 33 | main (void) 34 | { 35 | ffi_type *ffitypes[NARGS]; 36 | int i; 37 | ffi_cif cif; 38 | ffi_arg result = 0; 39 | uint8_t args[NARGS]; 40 | void *argptrs[NARGS]; 41 | 42 | for (i = 0; i < NARGS; ++i) 43 | ffitypes[i] = &ffi_type_uint8; 44 | 45 | CHECK (ffi_prep_cif (&cif, ABI_NUM, NARGS, 46 | &ffi_type_uint8, ffitypes) == FFI_OK); 47 | 48 | for (i = 0; i < NARGS; ++i) 49 | { 50 | args[i] = i; 51 | argptrs[i] = &args[i]; 52 | } 53 | ffi_call (&cif, FFI_FN (bar), &result, argptrs); 54 | 55 | CHECK (result == 21); 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /testsuite/libffi.call/strlen4.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check strlen function call with additional arguments. 3 | Limitations: none. 4 | PR: none. 5 | Originator: From the original ffitest.c */ 6 | 7 | /* { dg-do run } */ 8 | 9 | #include "ffitest.h" 10 | 11 | static size_t ABI_ATTR my_f(float a, char *s, int i) 12 | { 13 | return (size_t) ((int) strlen(s) + (int) a + i); 14 | } 15 | 16 | int main (void) 17 | { 18 | ffi_cif cif; 19 | ffi_type *args[MAX_ARGS]; 20 | void *values[MAX_ARGS]; 21 | ffi_arg rint; 22 | char *s; 23 | int v1; 24 | float v2; 25 | args[2] = &ffi_type_sint; 26 | args[1] = &ffi_type_pointer; 27 | args[0] = &ffi_type_float; 28 | values[2] = (void*) &v1; 29 | values[1] = (void*) &s; 30 | values[0] = (void*) &v2; 31 | 32 | /* Initialize the cif */ 33 | CHECK(ffi_prep_cif(&cif, ABI_NUM, 3, 34 | &ffi_type_sint, args) == FFI_OK); 35 | 36 | s = "a"; 37 | v1 = 1; 38 | v2 = 0.0; 39 | ffi_call(&cif, FFI_FN(my_f), &rint, values); 40 | CHECK(rint == 2); 41 | 42 | s = "1234567"; 43 | v2 = -1.0; 44 | v1 = -2; 45 | ffi_call(&cif, FFI_FN(my_f), &rint, values); 46 | CHECK(rint == 4); 47 | 48 | s = "1234567890123456789012345"; 49 | v2 = 1.0; 50 | v1 = 2; 51 | ffi_call(&cif, FFI_FN(my_f), &rint, values); 52 | CHECK(rint == 28); 53 | 54 | exit(0); 55 | } 56 | -------------------------------------------------------------------------------- /testsuite/libffi.call/float.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check return value float. 3 | Limitations: none. 4 | PR: none. 5 | Originator: From the original ffitest.c */ 6 | 7 | /* { dg-do run } */ 8 | 9 | #include "ffitest.h" 10 | 11 | static int floating(int a, float b, double c, long double d) 12 | { 13 | int i; 14 | 15 | i = (int) ((float)a/b + ((float)c/(float)d)); 16 | 17 | return i; 18 | } 19 | 20 | int main (void) 21 | { 22 | ffi_cif cif; 23 | ffi_type *args[MAX_ARGS]; 24 | void *values[MAX_ARGS]; 25 | ffi_arg rint; 26 | 27 | float f; 28 | signed int si1; 29 | double d; 30 | long double ld; 31 | 32 | args[0] = &ffi_type_sint; 33 | values[0] = &si1; 34 | args[1] = &ffi_type_float; 35 | values[1] = &f; 36 | args[2] = &ffi_type_double; 37 | values[2] = &d; 38 | args[3] = &ffi_type_longdouble; 39 | values[3] = &ld; 40 | 41 | /* Initialize the cif */ 42 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, 43 | &ffi_type_sint, args) == FFI_OK); 44 | 45 | si1 = 6; 46 | f = 3.14159; 47 | d = (double)1.0/(double)3.0; 48 | ld = 2.71828182846L; 49 | 50 | floating (si1, f, d, ld); 51 | 52 | ffi_call(&cif, FFI_FN(floating), &rint, values); 53 | 54 | printf ("%d vs %d\n", (int)rint, floating (si1, f, d, ld)); 55 | 56 | CHECK((int)rint == floating(si1, f, d, ld)); 57 | 58 | exit (0); 59 | } 60 | -------------------------------------------------------------------------------- /testsuite/libffi.complex/complex.inc: -------------------------------------------------------------------------------- 1 | /* -*-c-*-*/ 2 | #include "ffitest.h" 3 | #include 4 | 5 | static _Complex T_C_TYPE f_complex(_Complex T_C_TYPE c, int x, int *py) 6 | { 7 | c = -(2 * creal (c)) + (cimag (c) + 1)* I; 8 | *py += x; 9 | 10 | return c; 11 | } 12 | 13 | int main (void) 14 | { 15 | ffi_cif cif; 16 | ffi_type *args[MAX_ARGS]; 17 | void *values[MAX_ARGS]; 18 | 19 | _Complex T_C_TYPE tc_arg; 20 | _Complex T_C_TYPE tc_result; 21 | int tc_int_arg_x; 22 | int tc_y; 23 | int *tc_ptr_arg_y = &tc_y; 24 | 25 | args[0] = &T_FFI_TYPE; 26 | args[1] = &ffi_type_sint; 27 | args[2] = &ffi_type_pointer; 28 | values[0] = &tc_arg; 29 | values[1] = &tc_int_arg_x; 30 | values[2] = &tc_ptr_arg_y; 31 | 32 | /* Initialize the cif */ 33 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, 34 | &T_FFI_TYPE, args) == FFI_OK); 35 | 36 | tc_arg = 1 + 7 * I; 37 | tc_int_arg_x = 1234; 38 | tc_y = 9876; 39 | ffi_call(&cif, FFI_FN(f_complex), &tc_result, values); 40 | 41 | printf ("%f,%fi %f,%fi, x %d 1234, y %d 11110\n", 42 | T_CONV creal (tc_result), T_CONV cimag (tc_result), 43 | T_CONV creal (2.0), T_CONV creal (8.0), tc_int_arg_x, tc_y); 44 | 45 | CHECK (creal (tc_result) == -2); 46 | CHECK (cimag (tc_result) == 8); 47 | CHECK (tc_int_arg_x == 1234); 48 | CHECK (*tc_ptr_arg_y == 11110); 49 | 50 | exit(0); 51 | } 52 | -------------------------------------------------------------------------------- /m4/ax_require_defined.m4: -------------------------------------------------------------------------------- 1 | # =========================================================================== 2 | # https://www.gnu.org/software/autoconf-archive/ax_require_defined.html 3 | # =========================================================================== 4 | # 5 | # SYNOPSIS 6 | # 7 | # AX_REQUIRE_DEFINED(MACRO) 8 | # 9 | # DESCRIPTION 10 | # 11 | # AX_REQUIRE_DEFINED is a simple helper for making sure other macros have 12 | # been defined and thus are available for use. This avoids random issues 13 | # where a macro isn't expanded. Instead the configure script emits a 14 | # non-fatal: 15 | # 16 | # ./configure: line 1673: AX_CFLAGS_WARN_ALL: command not found 17 | # 18 | # It's like AC_REQUIRE except it doesn't expand the required macro. 19 | # 20 | # Here's an example: 21 | # 22 | # AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG]) 23 | # 24 | # LICENSE 25 | # 26 | # Copyright (c) 2014 Mike Frysinger 27 | # 28 | # Copying and distribution of this file, with or without modification, are 29 | # permitted in any medium without royalty provided the copyright notice 30 | # and this notice are preserved. This file is offered as-is, without any 31 | # warranty. 32 | 33 | #serial 2 34 | 35 | AC_DEFUN([AX_REQUIRE_DEFINED], [dnl 36 | m4_ifndef([$1], [m4_fatal([macro ]$1[ is not defined; is a m4 file missing?])]) 37 | ])dnl AX_REQUIRE_DEFINED 38 | -------------------------------------------------------------------------------- /testsuite/libffi.call/float1.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check return value double. 3 | Limitations: none. 4 | PR: none. 5 | Originator: From the original ffitest.c */ 6 | 7 | /* { dg-do run } */ 8 | #include "ffitest.h" 9 | #include "float.h" 10 | 11 | #include 12 | 13 | typedef union 14 | { 15 | double d; 16 | unsigned char c[sizeof (double)]; 17 | } value_type; 18 | 19 | #define CANARY 0xba 20 | 21 | static double dblit(float f) 22 | { 23 | return f/3.0; 24 | } 25 | 26 | int main (void) 27 | { 28 | ffi_cif cif; 29 | ffi_type *args[MAX_ARGS]; 30 | void *values[MAX_ARGS]; 31 | float f; 32 | value_type result[2]; 33 | unsigned int i; 34 | 35 | args[0] = &ffi_type_float; 36 | values[0] = &f; 37 | 38 | /* Initialize the cif */ 39 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 40 | &ffi_type_double, args) == FFI_OK); 41 | 42 | f = 3.14159; 43 | 44 | /* Put a canary in the return array. This is a regression test for 45 | a buffer overrun. */ 46 | memset(result[1].c, CANARY, sizeof (double)); 47 | 48 | ffi_call(&cif, FFI_FN(dblit), &result[0].d, values); 49 | 50 | /* These are not always the same!! Check for a reasonable delta */ 51 | 52 | CHECK(fabs(result[0].d - dblit(f)) < DBL_EPSILON); 53 | 54 | /* Check the canary. */ 55 | for (i = 0; i < sizeof (double); ++i) 56 | CHECK(result[1].c[i] == CANARY); 57 | 58 | exit(0); 59 | 60 | } 61 | -------------------------------------------------------------------------------- /man/ffi_prep_cif.3: -------------------------------------------------------------------------------- 1 | .Dd February 15, 2008 2 | .Dt ffi_prep_cif 3 3 | .Sh NAME 4 | .Nm ffi_prep_cif 5 | .Nd Prepare a 6 | .Nm ffi_cif 7 | structure for use with 8 | .Nm ffi_call 9 | . 10 | .Sh SYNOPSIS 11 | .In ffi.h 12 | .Ft ffi_status 13 | .Fo ffi_prep_cif 14 | .Fa "ffi_cif *cif" 15 | .Fa "ffi_abi abi" 16 | .Fa "unsigned int nargs" 17 | .Fa "ffi_type *rtype" 18 | .Fa "ffi_type **atypes" 19 | .Fc 20 | .Sh DESCRIPTION 21 | The 22 | .Nm ffi_prep_cif 23 | function prepares a 24 | .Nm ffi_cif 25 | structure for use with 26 | .Nm ffi_call 27 | . 28 | .Fa abi 29 | specifies a set of calling conventions to use. 30 | .Fa atypes 31 | is an array of 32 | .Fa nargs 33 | pointers to 34 | .Nm ffi_type 35 | structs that describe the data type, size and alignment of each argument. 36 | .Fa rtype 37 | points to an 38 | .Nm ffi_type 39 | that describes the data type, size and alignment of the 40 | return value. Note that to call a variadic function 41 | .Nm ffi_prep_cif_var 42 | must be used instead. 43 | .Sh RETURN VALUES 44 | Upon successful completion, 45 | .Nm ffi_prep_cif 46 | returns 47 | .Nm FFI_OK . 48 | It will return 49 | .Nm FFI_BAD_TYPEDEF 50 | if 51 | .Fa cif 52 | is 53 | .Nm NULL 54 | or 55 | .Fa atypes 56 | or 57 | .Fa rtype 58 | is malformed. If 59 | .Fa abi 60 | does not refer to a valid ABI, 61 | .Nm FFI_BAD_ABI 62 | will be returned. Available ABIs are 63 | defined in 64 | .Nm . 65 | .Sh SEE ALSO 66 | .Xr ffi 3 , 67 | .Xr ffi_call 3 , 68 | .Xr ffi_prep_cif_var 3 69 | -------------------------------------------------------------------------------- /testsuite/libffi.call/struct3.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check structures. 3 | Limitations: none. 4 | PR: none. 5 | Originator: From the original ffitest.c */ 6 | 7 | /* { dg-do run } */ 8 | #include "ffitest.h" 9 | 10 | typedef struct 11 | { 12 | int si; 13 | } test_structure_3; 14 | 15 | static test_structure_3 ABI_ATTR struct3(test_structure_3 ts) 16 | { 17 | ts.si = -(ts.si*2); 18 | 19 | return ts; 20 | } 21 | 22 | int main (void) 23 | { 24 | ffi_cif cif; 25 | ffi_type *args[MAX_ARGS]; 26 | void *values[MAX_ARGS]; 27 | int compare_value; 28 | ffi_type ts3_type; 29 | ffi_type *ts3_type_elements[2]; 30 | 31 | test_structure_3 ts3_arg; 32 | test_structure_3 *ts3_result = 33 | (test_structure_3 *) malloc (sizeof(test_structure_3)); 34 | 35 | ts3_type.size = 0; 36 | ts3_type.alignment = 0; 37 | ts3_type.type = FFI_TYPE_STRUCT; 38 | ts3_type.elements = ts3_type_elements; 39 | ts3_type_elements[0] = &ffi_type_sint; 40 | ts3_type_elements[1] = NULL; 41 | 42 | args[0] = &ts3_type; 43 | values[0] = &ts3_arg; 44 | 45 | /* Initialize the cif */ 46 | CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, 47 | &ts3_type, args) == FFI_OK); 48 | 49 | ts3_arg.si = -123; 50 | compare_value = ts3_arg.si; 51 | 52 | ffi_call(&cif, FFI_FN(struct3), ts3_result, values); 53 | 54 | printf ("%d %d\n", ts3_result->si, -(compare_value*2)); 55 | 56 | CHECK(ts3_result->si == -(compare_value*2)); 57 | 58 | free (ts3_result); 59 | exit(0); 60 | } 61 | -------------------------------------------------------------------------------- /testsuite/libffi.call/uninitialized.c: -------------------------------------------------------------------------------- 1 | /* { dg-do run } */ 2 | #include "ffitest.h" 3 | 4 | typedef struct 5 | { 6 | unsigned char uc; 7 | double d; 8 | unsigned int ui; 9 | } test_structure_1; 10 | 11 | static test_structure_1 struct1(test_structure_1 ts) 12 | { 13 | ts.uc++; 14 | ts.d--; 15 | ts.ui++; 16 | 17 | return ts; 18 | } 19 | 20 | int main (void) 21 | { 22 | ffi_cif cif; 23 | ffi_type *args[MAX_ARGS]; 24 | void *values[MAX_ARGS]; 25 | ffi_type ts1_type; 26 | ffi_type *ts1_type_elements[4]; 27 | 28 | memset(&cif, 1, sizeof(cif)); 29 | ts1_type.size = 0; 30 | ts1_type.alignment = 0; 31 | ts1_type.type = FFI_TYPE_STRUCT; 32 | ts1_type.elements = ts1_type_elements; 33 | ts1_type_elements[0] = &ffi_type_uchar; 34 | ts1_type_elements[1] = &ffi_type_double; 35 | ts1_type_elements[2] = &ffi_type_uint; 36 | ts1_type_elements[3] = NULL; 37 | 38 | test_structure_1 ts1_arg; 39 | /* This is a hack to get a properly aligned result buffer */ 40 | test_structure_1 *ts1_result = 41 | (test_structure_1 *) malloc (sizeof(test_structure_1)); 42 | 43 | args[0] = &ts1_type; 44 | values[0] = &ts1_arg; 45 | 46 | /* Initialize the cif */ 47 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 48 | &ts1_type, args) == FFI_OK); 49 | 50 | ts1_arg.uc = '\x01'; 51 | ts1_arg.d = 3.14159; 52 | ts1_arg.ui = 555; 53 | 54 | ffi_call(&cif, FFI_FN(struct1), ts1_result, values); 55 | 56 | CHECK(ts1_result->ui == 556); 57 | CHECK(ts1_result->d == 3.14159 - 1); 58 | 59 | free (ts1_result); 60 | exit(0); 61 | } 62 | -------------------------------------------------------------------------------- /testsuite/libffi.call/float4.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check denorm double value. 3 | Limitations: none. 4 | PR: PR26483. 5 | Originator: From the original ffitest.c */ 6 | 7 | /* { dg-do run } */ 8 | /* { dg-options "-mieee" { target alpha*-*-* } } */ 9 | 10 | #include "ffitest.h" 11 | #include "float.h" 12 | 13 | typedef union 14 | { 15 | double d; 16 | unsigned char c[sizeof (double)]; 17 | } value_type; 18 | 19 | #define CANARY 0xba 20 | 21 | static double dblit(double d) 22 | { 23 | return d; 24 | } 25 | 26 | int main (void) 27 | { 28 | ffi_cif cif; 29 | ffi_type *args[MAX_ARGS]; 30 | void *values[MAX_ARGS]; 31 | double d; 32 | value_type result[2]; 33 | unsigned int i; 34 | 35 | args[0] = &ffi_type_double; 36 | values[0] = &d; 37 | 38 | /* Initialize the cif */ 39 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 40 | &ffi_type_double, args) == FFI_OK); 41 | 42 | d = DBL_MIN / 2; 43 | 44 | /* Put a canary in the return array. This is a regression test for 45 | a buffer overrun. */ 46 | memset(result[1].c, CANARY, sizeof (double)); 47 | 48 | ffi_call(&cif, FFI_FN(dblit), &result[0].d, values); 49 | 50 | /* The standard delta check doesn't work for denorms. Since we didn't do 51 | any arithmetic, we should get the original result back, and hence an 52 | exact check should be OK here. */ 53 | 54 | CHECK(result[0].d == dblit(d)); 55 | 56 | /* Check the canary. */ 57 | for (i = 0; i < sizeof (double); ++i) 58 | CHECK(result[1].c[i] == CANARY); 59 | 60 | exit(0); 61 | 62 | } 63 | -------------------------------------------------------------------------------- /testsuite/libffi.call/many.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check return value float, with many arguments 3 | Limitations: none. 4 | PR: none. 5 | Originator: From the original ffitest.c */ 6 | 7 | /* { dg-do run } */ 8 | #include "ffitest.h" 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | static float ABI_ATTR many(float f1, float f2, float f3, float f4, float f5, float f6, float f7, float f8, float f9, float f10, float f11, float f12, float f13) 15 | { 16 | #if 0 17 | printf("%f %f %f %f %f %f %f %f %f %f %f %f %f\n", 18 | (double) f1, (double) f2, (double) f3, (double) f4, (double) f5, 19 | (double) f6, (double) f7, (double) f8, (double) f9, (double) f10, 20 | (double) f11, (double) f12, (double) f13); 21 | #endif 22 | 23 | return f1+f2+f3+f4+f5+f6+f7+f8+f9+f10+f11+f12+f13; 24 | } 25 | 26 | int main (void) 27 | { 28 | ffi_cif cif; 29 | ffi_type *args[13]; 30 | void *values[13]; 31 | float fa[13]; 32 | float f, ff; 33 | int i; 34 | 35 | for (i = 0; i < 13; i++) 36 | { 37 | args[i] = &ffi_type_float; 38 | values[i] = &fa[i]; 39 | fa[i] = (float) i; 40 | } 41 | 42 | /* Initialize the cif */ 43 | CHECK(ffi_prep_cif(&cif, ABI_NUM, 13, 44 | &ffi_type_float, args) == FFI_OK); 45 | 46 | ffi_call(&cif, FFI_FN(many), &f, values); 47 | 48 | ff = many(fa[0], fa[1], 49 | fa[2], fa[3], 50 | fa[4], fa[5], 51 | fa[6], fa[7], 52 | fa[8], fa[9], 53 | fa[10],fa[11],fa[12]); 54 | 55 | if (fabs(f - ff) < FLT_EPSILON) 56 | exit(0); 57 | else 58 | abort(); 59 | } 60 | -------------------------------------------------------------------------------- /testsuite/libffi.call/promotion.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Promotion test. 3 | Limitations: none. 4 | PR: none. 5 | Originator: From the original ffitest.c */ 6 | 7 | /* { dg-do run } */ 8 | #include "ffitest.h" 9 | static int promotion(signed char sc, signed short ss, 10 | unsigned char uc, unsigned short us) 11 | { 12 | int r = (int) sc + (int) ss + (int) uc + (int) us; 13 | 14 | return r; 15 | } 16 | 17 | int main (void) 18 | { 19 | ffi_cif cif; 20 | ffi_type *args[MAX_ARGS]; 21 | void *values[MAX_ARGS]; 22 | ffi_arg rint; 23 | signed char sc; 24 | unsigned char uc; 25 | signed short ss; 26 | unsigned short us; 27 | unsigned long ul; 28 | 29 | args[0] = &ffi_type_schar; 30 | args[1] = &ffi_type_sshort; 31 | args[2] = &ffi_type_uchar; 32 | args[3] = &ffi_type_ushort; 33 | values[0] = ≻ 34 | values[1] = &ss; 35 | values[2] = &uc; 36 | values[3] = &us; 37 | 38 | /* Initialize the cif */ 39 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, 40 | &ffi_type_sint, args) == FFI_OK); 41 | 42 | us = 0; 43 | ul = 0; 44 | 45 | for (sc = (signed char) -127; 46 | sc <= (signed char) 120; sc += 1) 47 | for (ss = -30000; ss <= 30000; ss += 10000) 48 | for (uc = (unsigned char) 0; 49 | uc <= (unsigned char) 200; uc += 20) 50 | for (us = 0; us <= 60000; us += 10000) 51 | { 52 | ul++; 53 | ffi_call(&cif, FFI_FN(promotion), &rint, values); 54 | CHECK((int)rint == (signed char) sc + (signed short) ss + 55 | (unsigned char) uc + (unsigned short) us); 56 | } 57 | printf("%lu promotion tests run\n", ul); 58 | exit(0); 59 | } 60 | -------------------------------------------------------------------------------- /testsuite/libffi.call/struct4.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check structures. 3 | Limitations: none. 4 | PR: none. 5 | Originator: From the original ffitest.c */ 6 | 7 | /* { dg-do run } */ 8 | #include "ffitest.h" 9 | 10 | typedef struct 11 | { 12 | unsigned ui1; 13 | unsigned ui2; 14 | unsigned ui3; 15 | } test_structure_4; 16 | 17 | static test_structure_4 ABI_ATTR struct4(test_structure_4 ts) 18 | { 19 | ts.ui3 = ts.ui1 * ts.ui2 * ts.ui3; 20 | 21 | return ts; 22 | } 23 | 24 | int main (void) 25 | { 26 | ffi_cif cif; 27 | ffi_type *args[MAX_ARGS]; 28 | void *values[MAX_ARGS]; 29 | ffi_type ts4_type; 30 | ffi_type *ts4_type_elements[4]; 31 | 32 | test_structure_4 ts4_arg; 33 | 34 | /* This is a hack to get a properly aligned result buffer */ 35 | test_structure_4 *ts4_result = 36 | (test_structure_4 *) malloc (sizeof(test_structure_4)); 37 | 38 | ts4_type.size = 0; 39 | ts4_type.alignment = 0; 40 | ts4_type.type = FFI_TYPE_STRUCT; 41 | ts4_type.elements = ts4_type_elements; 42 | ts4_type_elements[0] = &ffi_type_uint; 43 | ts4_type_elements[1] = &ffi_type_uint; 44 | ts4_type_elements[2] = &ffi_type_uint; 45 | ts4_type_elements[3] = NULL; 46 | 47 | args[0] = &ts4_type; 48 | values[0] = &ts4_arg; 49 | 50 | /* Initialize the cif */ 51 | CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ts4_type, args) == FFI_OK); 52 | 53 | ts4_arg.ui1 = 2; 54 | ts4_arg.ui2 = 3; 55 | ts4_arg.ui3 = 4; 56 | 57 | ffi_call (&cif, FFI_FN(struct4), ts4_result, values); 58 | 59 | CHECK(ts4_result->ui3 == 2U * 3U * 4U); 60 | 61 | 62 | free (ts4_result); 63 | exit(0); 64 | } 65 | -------------------------------------------------------------------------------- /testsuite/libffi.call/struct6.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check structures. 3 | Limitations: none. 4 | PR: none. 5 | Originator: From the original ffitest.c */ 6 | 7 | /* { dg-do run } */ 8 | #include "ffitest.h" 9 | typedef struct 10 | { 11 | float f; 12 | double d; 13 | } test_structure_6; 14 | 15 | static test_structure_6 ABI_ATTR struct6 (test_structure_6 ts) 16 | { 17 | ts.f += 1; 18 | ts.d += 1; 19 | 20 | return ts; 21 | } 22 | 23 | int main (void) 24 | { 25 | ffi_cif cif; 26 | ffi_type *args[MAX_ARGS]; 27 | void *values[MAX_ARGS]; 28 | ffi_type ts6_type; 29 | ffi_type *ts6_type_elements[3]; 30 | 31 | test_structure_6 ts6_arg; 32 | 33 | /* This is a hack to get a properly aligned result buffer */ 34 | test_structure_6 *ts6_result = 35 | (test_structure_6 *) malloc (sizeof(test_structure_6)); 36 | 37 | ts6_type.size = 0; 38 | ts6_type.alignment = 0; 39 | ts6_type.type = FFI_TYPE_STRUCT; 40 | ts6_type.elements = ts6_type_elements; 41 | ts6_type_elements[0] = &ffi_type_float; 42 | ts6_type_elements[1] = &ffi_type_double; 43 | ts6_type_elements[2] = NULL; 44 | 45 | args[0] = &ts6_type; 46 | values[0] = &ts6_arg; 47 | 48 | /* Initialize the cif */ 49 | CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ts6_type, args) == FFI_OK); 50 | 51 | ts6_arg.f = 5.55f; 52 | ts6_arg.d = 6.66; 53 | 54 | printf ("%g\n", ts6_arg.f); 55 | printf ("%g\n", ts6_arg.d); 56 | 57 | ffi_call(&cif, FFI_FN(struct6), ts6_result, values); 58 | 59 | CHECK(ts6_result->f == 5.55f + 1); 60 | CHECK(ts6_result->d == 6.66 + 1); 61 | 62 | free (ts6_result); 63 | exit(0); 64 | } 65 | -------------------------------------------------------------------------------- /man/ffi_prep_cif_var.3: -------------------------------------------------------------------------------- 1 | .Dd January 25, 2011 2 | .Dt ffi_prep_cif_var 3 3 | .Sh NAME 4 | .Nm ffi_prep_cif_var 5 | .Nd Prepare a 6 | .Nm ffi_cif 7 | structure for use with 8 | .Nm ffi_call 9 | for variadic functions. 10 | .Sh SYNOPSIS 11 | .In ffi.h 12 | .Ft ffi_status 13 | .Fo ffi_prep_cif_var 14 | .Fa "ffi_cif *cif" 15 | .Fa "ffi_abi abi" 16 | .Fa "unsigned int nfixedargs" 17 | .Fa "unsigned int ntotalargs" 18 | .Fa "ffi_type *rtype" 19 | .Fa "ffi_type **atypes" 20 | .Fc 21 | .Sh DESCRIPTION 22 | The 23 | .Nm ffi_prep_cif_var 24 | function prepares a 25 | .Nm ffi_cif 26 | structure for use with 27 | .Nm ffi_call 28 | for variadic functions. 29 | .Fa abi 30 | specifies a set of calling conventions to use. 31 | .Fa atypes 32 | is an array of 33 | .Fa ntotalargs 34 | pointers to 35 | .Nm ffi_type 36 | structs that describe the data type, size and alignment of each argument. 37 | .Fa rtype 38 | points to an 39 | .Nm ffi_type 40 | that describes the data type, size and alignment of the 41 | return value. 42 | .Fa nfixedargs 43 | must contain the number of fixed (non-variadic) arguments. 44 | Note that to call a non-variadic function 45 | .Nm ffi_prep_cif 46 | must be used. 47 | .Sh RETURN VALUES 48 | Upon successful completion, 49 | .Nm ffi_prep_cif_var 50 | returns 51 | .Nm FFI_OK . 52 | It will return 53 | .Nm FFI_BAD_TYPEDEF 54 | if 55 | .Fa cif 56 | is 57 | .Nm NULL 58 | or 59 | .Fa atypes 60 | or 61 | .Fa rtype 62 | is malformed. If 63 | .Fa abi 64 | does not refer to a valid ABI, 65 | .Nm FFI_BAD_ABI 66 | will be returned. Available ABIs are 67 | defined in 68 | .Nm 69 | . 70 | .Sh SEE ALSO 71 | .Xr ffi 3 , 72 | .Xr ffi_call 3 , 73 | .Xr ffi_prep_cif 3 74 | -------------------------------------------------------------------------------- /testsuite/libffi.closures/cls_dbls_struct.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call, closure_call 2 | Purpose: Check double arguments in structs. 3 | Limitations: none. 4 | PR: none. 5 | Originator: Blake Chaffin 6/23/2007 */ 6 | 7 | /* { dg-do run } */ 8 | 9 | #include "ffitest.h" 10 | 11 | typedef struct Dbls { 12 | double x; 13 | double y; 14 | } Dbls; 15 | 16 | void 17 | closure_test_fn(Dbls p) 18 | { 19 | printf("%.1f %.1f\n", p.x, p.y); 20 | } 21 | 22 | void 23 | closure_test_gn(ffi_cif* cif __UNUSED__, void* resp __UNUSED__, 24 | void** args, void* userdata __UNUSED__) 25 | { 26 | closure_test_fn(*(Dbls*)args[0]); 27 | } 28 | 29 | int main(int argc __UNUSED__, char** argv __UNUSED__) 30 | { 31 | ffi_cif cif; 32 | 33 | void *code; 34 | ffi_closure* pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); 35 | ffi_type* cl_arg_types[1]; 36 | 37 | ffi_type ts1_type; 38 | ffi_type* ts1_type_elements[4]; 39 | 40 | Dbls arg = { 1.0, 2.0 }; 41 | 42 | ts1_type.size = 0; 43 | ts1_type.alignment = 0; 44 | ts1_type.type = FFI_TYPE_STRUCT; 45 | ts1_type.elements = ts1_type_elements; 46 | 47 | ts1_type_elements[0] = &ffi_type_double; 48 | ts1_type_elements[1] = &ffi_type_double; 49 | ts1_type_elements[2] = NULL; 50 | 51 | cl_arg_types[0] = &ts1_type; 52 | 53 | /* Initialize the cif */ 54 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 55 | &ffi_type_void, cl_arg_types) == FFI_OK); 56 | 57 | CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_gn, NULL, code) == FFI_OK); 58 | 59 | ((void*(*)(Dbls))(code))(arg); 60 | /* { dg-output "1.0 2.0" } */ 61 | 62 | closure_test_fn(arg); 63 | /* { dg-output "\n1.0 2.0" } */ 64 | 65 | return 0; 66 | } 67 | -------------------------------------------------------------------------------- /msvc_build/aarch64/Ffi_staticLib.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.28302.56 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Ffi_staticLib_arm64", "Ffi_staticLib.vcxproj", "{115502C0-BE05-4767-BF19-5C87D805FAD6}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|ARM64 = Debug|ARM64 11 | Debug|x64 = Debug|x64 12 | Debug|x86 = Debug|x86 13 | Release|ARM64 = Release|ARM64 14 | Release|x64 = Release|x64 15 | Release|x86 = Release|x86 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {115502C0-BE05-4767-BF19-5C87D805FAD6}.Debug|ARM64.ActiveCfg = Debug|ARM64 19 | {115502C0-BE05-4767-BF19-5C87D805FAD6}.Debug|ARM64.Build.0 = Debug|ARM64 20 | {115502C0-BE05-4767-BF19-5C87D805FAD6}.Debug|x64.ActiveCfg = Debug|ARM64 21 | {115502C0-BE05-4767-BF19-5C87D805FAD6}.Debug|x86.ActiveCfg = Debug|ARM64 22 | {115502C0-BE05-4767-BF19-5C87D805FAD6}.Release|ARM64.ActiveCfg = Release|ARM64 23 | {115502C0-BE05-4767-BF19-5C87D805FAD6}.Release|ARM64.Build.0 = Release|ARM64 24 | {115502C0-BE05-4767-BF19-5C87D805FAD6}.Release|x64.ActiveCfg = Release|ARM64 25 | {115502C0-BE05-4767-BF19-5C87D805FAD6}.Release|x86.ActiveCfg = Release|ARM64 26 | EndGlobalSection 27 | GlobalSection(SolutionProperties) = preSolution 28 | HideSolutionNode = FALSE 29 | EndGlobalSection 30 | GlobalSection(ExtensibilityGlobals) = postSolution 31 | SolutionGuid = {241C54C7-20DD-4897-9376-E6B6D1B43BD5} 32 | EndGlobalSection 33 | EndGlobal 34 | -------------------------------------------------------------------------------- /testsuite/libffi.closures/closure_simple.c: -------------------------------------------------------------------------------- 1 | /* Area: closure_call 2 | Purpose: Check simple closure handling with all ABIs 3 | Limitations: none. 4 | PR: none. 5 | Originator: */ 6 | 7 | /* { dg-do run } */ 8 | #include "ffitest.h" 9 | 10 | static void 11 | closure_test(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata) 12 | { 13 | *(ffi_arg*)resp = 14 | (int)*(int *)args[0] + (int)(*(int *)args[1]) 15 | + (int)(*(int *)args[2]) + (int)(*(int *)args[3]) 16 | + (int)(intptr_t)userdata; 17 | 18 | printf("%d %d %d %d: %d\n", 19 | (int)*(int *)args[0], (int)(*(int *)args[1]), 20 | (int)(*(int *)args[2]), (int)(*(int *)args[3]), 21 | (int)*(ffi_arg *)resp); 22 | 23 | } 24 | 25 | typedef int (ABI_ATTR *closure_test_type0)(int, int, int, int); 26 | 27 | int main (void) 28 | { 29 | ffi_cif cif; 30 | void *code; 31 | ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); 32 | ffi_type * cl_arg_types[17]; 33 | int res; 34 | 35 | cl_arg_types[0] = &ffi_type_uint; 36 | cl_arg_types[1] = &ffi_type_uint; 37 | cl_arg_types[2] = &ffi_type_uint; 38 | cl_arg_types[3] = &ffi_type_uint; 39 | cl_arg_types[4] = NULL; 40 | 41 | /* Initialize the cif */ 42 | CHECK(ffi_prep_cif(&cif, ABI_NUM, 4, 43 | &ffi_type_sint, cl_arg_types) == FFI_OK); 44 | 45 | CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test, 46 | (void *) 3 /* userdata */, code) == FFI_OK); 47 | 48 | res = (*(closure_test_type0)code)(0, 1, 2, 3); 49 | /* { dg-output "0 1 2 3: 9" } */ 50 | 51 | printf("res: %d\n",res); 52 | /* { dg-output "\nres: 9" } */ 53 | 54 | exit(0); 55 | } 56 | -------------------------------------------------------------------------------- /testsuite/libffi.call/struct1.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check structures. 3 | Limitations: none. 4 | PR: none. 5 | Originator: From the original ffitest.c */ 6 | 7 | /* { dg-do run } */ 8 | #include "ffitest.h" 9 | 10 | typedef struct 11 | { 12 | unsigned char uc; 13 | double d; 14 | unsigned int ui; 15 | } test_structure_1; 16 | 17 | static test_structure_1 ABI_ATTR struct1(test_structure_1 ts) 18 | { 19 | ts.uc++; 20 | ts.d--; 21 | ts.ui++; 22 | 23 | return ts; 24 | } 25 | 26 | int main (void) 27 | { 28 | ffi_cif cif; 29 | ffi_type *args[MAX_ARGS]; 30 | void *values[MAX_ARGS]; 31 | ffi_type ts1_type; 32 | ffi_type *ts1_type_elements[4]; 33 | 34 | test_structure_1 ts1_arg; 35 | 36 | /* This is a hack to get a properly aligned result buffer */ 37 | test_structure_1 *ts1_result = 38 | (test_structure_1 *) malloc (sizeof(test_structure_1)); 39 | 40 | ts1_type.size = 0; 41 | ts1_type.alignment = 0; 42 | ts1_type.type = FFI_TYPE_STRUCT; 43 | ts1_type.elements = ts1_type_elements; 44 | ts1_type_elements[0] = &ffi_type_uchar; 45 | ts1_type_elements[1] = &ffi_type_double; 46 | ts1_type_elements[2] = &ffi_type_uint; 47 | ts1_type_elements[3] = NULL; 48 | 49 | args[0] = &ts1_type; 50 | values[0] = &ts1_arg; 51 | 52 | /* Initialize the cif */ 53 | CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, 54 | &ts1_type, args) == FFI_OK); 55 | 56 | ts1_arg.uc = '\x01'; 57 | ts1_arg.d = 3.14159; 58 | ts1_arg.ui = 555; 59 | 60 | ffi_call(&cif, FFI_FN(struct1), ts1_result, values); 61 | 62 | CHECK(ts1_result->ui == 556); 63 | CHECK(ts1_result->d == 3.14159 - 1); 64 | 65 | free (ts1_result); 66 | exit(0); 67 | } 68 | -------------------------------------------------------------------------------- /testsuite/libffi.call/struct5.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check structures. 3 | Limitations: none. 4 | PR: none. 5 | Originator: From the original ffitest.c */ 6 | 7 | /* { dg-do run } */ 8 | #include "ffitest.h" 9 | typedef struct 10 | { 11 | char c1; 12 | char c2; 13 | } test_structure_5; 14 | 15 | static test_structure_5 ABI_ATTR struct5(test_structure_5 ts1, test_structure_5 ts2) 16 | { 17 | ts1.c1 += ts2.c1; 18 | ts1.c2 -= ts2.c2; 19 | 20 | return ts1; 21 | } 22 | 23 | int main (void) 24 | { 25 | ffi_cif cif; 26 | ffi_type *args[MAX_ARGS]; 27 | void *values[MAX_ARGS]; 28 | ffi_type ts5_type; 29 | ffi_type *ts5_type_elements[3]; 30 | 31 | test_structure_5 ts5_arg1, ts5_arg2; 32 | 33 | /* This is a hack to get a properly aligned result buffer */ 34 | test_structure_5 *ts5_result = 35 | (test_structure_5 *) malloc (sizeof(test_structure_5)); 36 | 37 | ts5_type.size = 0; 38 | ts5_type.alignment = 0; 39 | ts5_type.type = FFI_TYPE_STRUCT; 40 | ts5_type.elements = ts5_type_elements; 41 | ts5_type_elements[0] = &ffi_type_schar; 42 | ts5_type_elements[1] = &ffi_type_schar; 43 | ts5_type_elements[2] = NULL; 44 | 45 | args[0] = &ts5_type; 46 | args[1] = &ts5_type; 47 | values[0] = &ts5_arg1; 48 | values[1] = &ts5_arg2; 49 | 50 | /* Initialize the cif */ 51 | CHECK(ffi_prep_cif(&cif, ABI_NUM, 2, &ts5_type, args) == FFI_OK); 52 | 53 | ts5_arg1.c1 = 2; 54 | ts5_arg1.c2 = 6; 55 | ts5_arg2.c1 = 5; 56 | ts5_arg2.c2 = 3; 57 | 58 | ffi_call (&cif, FFI_FN(struct5), ts5_result, values); 59 | 60 | CHECK(ts5_result->c1 == 7); 61 | CHECK(ts5_result->c2 == 3); 62 | 63 | 64 | free (ts5_result); 65 | exit(0); 66 | } 67 | -------------------------------------------------------------------------------- /testsuite/libffi.call/struct9.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check structures. 3 | Limitations: none. 4 | PR: none. 5 | Originator: From the original ffitest.c */ 6 | 7 | /* { dg-do run } */ 8 | #include "ffitest.h" 9 | 10 | typedef struct 11 | { 12 | float f; 13 | int i; 14 | } test_structure_9; 15 | 16 | static test_structure_9 ABI_ATTR struct9 (test_structure_9 ts) 17 | { 18 | ts.f += 1; 19 | ts.i += 1; 20 | 21 | return ts; 22 | } 23 | 24 | int main (void) 25 | { 26 | ffi_cif cif; 27 | ffi_type *args[MAX_ARGS]; 28 | void *values[MAX_ARGS]; 29 | ffi_type ts9_type; 30 | ffi_type *ts9_type_elements[3]; 31 | 32 | test_structure_9 ts9_arg; 33 | 34 | /* This is a hack to get a properly aligned result buffer */ 35 | test_structure_9 *ts9_result = 36 | (test_structure_9 *) malloc (sizeof(test_structure_9)); 37 | 38 | ts9_type.size = 0; 39 | ts9_type.alignment = 0; 40 | ts9_type.type = FFI_TYPE_STRUCT; 41 | ts9_type.elements = ts9_type_elements; 42 | ts9_type_elements[0] = &ffi_type_float; 43 | ts9_type_elements[1] = &ffi_type_sint; 44 | ts9_type_elements[2] = NULL; 45 | 46 | args[0] = &ts9_type; 47 | values[0] = &ts9_arg; 48 | 49 | /* Initialize the cif */ 50 | CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ts9_type, args) == FFI_OK); 51 | 52 | ts9_arg.f = 5.55f; 53 | ts9_arg.i = 5; 54 | 55 | printf ("%g\n", ts9_arg.f); 56 | printf ("%d\n", ts9_arg.i); 57 | 58 | ffi_call(&cif, FFI_FN(struct9), ts9_result, values); 59 | 60 | printf ("%g\n", ts9_result->f); 61 | printf ("%d\n", ts9_result->i); 62 | 63 | CHECK(ts9_result->f == 5.55f + 1); 64 | CHECK(ts9_result->i == 5 + 1); 65 | 66 | free (ts9_result); 67 | exit(0); 68 | } 69 | -------------------------------------------------------------------------------- /testsuite/libffi.call/struct2.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check structures. 3 | Limitations: none. 4 | PR: none. 5 | Originator: From the original ffitest.c */ 6 | 7 | /* { dg-do run } */ 8 | #include "ffitest.h" 9 | 10 | typedef struct 11 | { 12 | double d1; 13 | double d2; 14 | } test_structure_2; 15 | 16 | static test_structure_2 ABI_ATTR struct2(test_structure_2 ts) 17 | { 18 | ts.d1--; 19 | ts.d2--; 20 | 21 | return ts; 22 | } 23 | 24 | int main (void) 25 | { 26 | ffi_cif cif; 27 | ffi_type *args[MAX_ARGS]; 28 | void *values[MAX_ARGS]; 29 | test_structure_2 ts2_arg; 30 | ffi_type ts2_type; 31 | ffi_type *ts2_type_elements[3]; 32 | 33 | /* This is a hack to get a properly aligned result buffer */ 34 | test_structure_2 *ts2_result = 35 | (test_structure_2 *) malloc (sizeof(test_structure_2)); 36 | 37 | ts2_type.size = 0; 38 | ts2_type.alignment = 0; 39 | ts2_type.type = FFI_TYPE_STRUCT; 40 | ts2_type.elements = ts2_type_elements; 41 | ts2_type_elements[0] = &ffi_type_double; 42 | ts2_type_elements[1] = &ffi_type_double; 43 | ts2_type_elements[2] = NULL; 44 | 45 | args[0] = &ts2_type; 46 | values[0] = &ts2_arg; 47 | 48 | /* Initialize the cif */ 49 | CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ts2_type, args) == FFI_OK); 50 | 51 | ts2_arg.d1 = 5.55; 52 | ts2_arg.d2 = 6.66; 53 | 54 | printf ("%g\n", ts2_arg.d1); 55 | printf ("%g\n", ts2_arg.d2); 56 | 57 | ffi_call(&cif, FFI_FN(struct2), ts2_result, values); 58 | 59 | printf ("%g\n", ts2_result->d1); 60 | printf ("%g\n", ts2_result->d2); 61 | 62 | CHECK(ts2_result->d1 == 5.55 - 1); 63 | CHECK(ts2_result->d2 == 6.66 - 1); 64 | 65 | free (ts2_result); 66 | exit(0); 67 | } 68 | -------------------------------------------------------------------------------- /testsuite/libffi.closures/cls_ulonglong.c: -------------------------------------------------------------------------------- 1 | /* Area: closure_call 2 | Purpose: Check return value long long. 3 | Limitations: none. 4 | PR: none. 5 | Originator: 20030828 */ 6 | 7 | /* { dg-do run } */ 8 | /* { dg-options "-Wno-format" { target alpha*-dec-osf* } } */ 9 | #include "ffitest.h" 10 | 11 | static void cls_ret_ulonglong_fn(ffi_cif* cif __UNUSED__, void* resp, 12 | void** args, void* userdata __UNUSED__) 13 | { 14 | *(unsigned long long *)resp= 0xfffffffffffffffLL ^ *(unsigned long long *)args[0]; 15 | 16 | printf("%" PRIuLL ": %" PRIuLL "\n",*(unsigned long long *)args[0], 17 | *(unsigned long long *)(resp)); 18 | } 19 | typedef unsigned long long (*cls_ret_ulonglong)(unsigned long long); 20 | 21 | int main (void) 22 | { 23 | ffi_cif cif; 24 | void *code; 25 | ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); 26 | ffi_type * cl_arg_types[2]; 27 | unsigned long long res; 28 | 29 | cl_arg_types[0] = &ffi_type_uint64; 30 | cl_arg_types[1] = NULL; 31 | 32 | /* Initialize the cif */ 33 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 34 | &ffi_type_uint64, cl_arg_types) == FFI_OK); 35 | CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_ulonglong_fn, NULL, code) == FFI_OK); 36 | res = (*((cls_ret_ulonglong)code))(214LL); 37 | /* { dg-output "214: 1152921504606846761" } */ 38 | printf("res: %" PRIdLL "\n", res); 39 | /* { dg-output "\nres: 1152921504606846761" } */ 40 | 41 | res = (*((cls_ret_ulonglong)code))(9223372035854775808LL); 42 | /* { dg-output "\n9223372035854775808: 8070450533247928831" } */ 43 | printf("res: %" PRIdLL "\n", res); 44 | /* { dg-output "\nres: 8070450533247928831" } */ 45 | 46 | exit(0); 47 | } 48 | -------------------------------------------------------------------------------- /testsuite/libffi.call/float2.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check return value long double. 3 | Limitations: none. 4 | PR: none. 5 | Originator: From the original ffitest.c */ 6 | /* { dg-do run } */ 7 | 8 | #include "ffitest.h" 9 | #include "float.h" 10 | 11 | #include 12 | 13 | static long double ldblit(float f) 14 | { 15 | return (long double) (((long double) f)/ (long double) 3.0); 16 | } 17 | 18 | int main (void) 19 | { 20 | ffi_cif cif; 21 | ffi_type *args[MAX_ARGS]; 22 | void *values[MAX_ARGS]; 23 | float f; 24 | long double ld; 25 | long double original; 26 | 27 | args[0] = &ffi_type_float; 28 | values[0] = &f; 29 | 30 | /* Initialize the cif */ 31 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 32 | &ffi_type_longdouble, args) == FFI_OK); 33 | 34 | f = 3.14159; 35 | 36 | #if defined(__sun) && defined(__GNUC__) 37 | /* long double support under SunOS/gcc is pretty much non-existent. 38 | You'll get the odd bus error in library routines like printf() */ 39 | #else 40 | printf ("%Lf\n", ldblit(f)); 41 | #endif 42 | 43 | ld = 666; 44 | ffi_call(&cif, FFI_FN(ldblit), &ld, values); 45 | 46 | #if defined(__sun) && defined(__GNUC__) 47 | /* long double support under SunOS/gcc is pretty much non-existent. 48 | You'll get the odd bus error in library routines like printf() */ 49 | #else 50 | printf ("%Lf, %Lf, %Lf, %Lf\n", ld, ldblit(f), ld - ldblit(f), LDBL_EPSILON); 51 | #endif 52 | 53 | /* These are not always the same!! Check for a reasonable delta */ 54 | original = ldblit(f); 55 | if (((ld > original) ? (ld - original) : (original - ld)) < LDBL_EPSILON) 56 | puts("long double return value tests ok!"); 57 | else 58 | CHECK(0); 59 | 60 | exit(0); 61 | } 62 | -------------------------------------------------------------------------------- /testsuite/libffi.call/many_double.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check return value double, with many arguments 3 | Limitations: none. 4 | PR: none. 5 | Originator: From the original ffitest.c */ 6 | 7 | /* { dg-do run } */ 8 | #include "ffitest.h" 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | static double many(double f1, 15 | double f2, 16 | double f3, 17 | double f4, 18 | double f5, 19 | double f6, 20 | double f7, 21 | double f8, 22 | double f9, 23 | double f10, 24 | double f11, 25 | double f12, 26 | double f13) 27 | { 28 | #if 0 29 | printf("%f %f %f %f %f %f %f %f %f %f %f %f %f\n", 30 | (double) f1, (double) f2, (double) f3, (double) f4, (double) f5, 31 | (double) f6, (double) f7, (double) f8, (double) f9, (double) f10, 32 | (double) f11, (double) f12, (double) f13); 33 | #endif 34 | 35 | return ((f1/f2+f3/f4+f5/f6+f7/f8+f9/f10+f11/f12) * f13); 36 | } 37 | 38 | int main (void) 39 | { 40 | ffi_cif cif; 41 | ffi_type *args[13]; 42 | void *values[13]; 43 | double fa[13]; 44 | double f, ff; 45 | int i; 46 | 47 | for (i = 0; i < 13; i++) 48 | { 49 | args[i] = &ffi_type_double; 50 | values[i] = &fa[i]; 51 | fa[i] = (double) i; 52 | } 53 | 54 | /* Initialize the cif */ 55 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 13, 56 | &ffi_type_double, args) == FFI_OK); 57 | 58 | ffi_call(&cif, FFI_FN(many), &f, values); 59 | 60 | ff = many(fa[0], fa[1], 61 | fa[2], fa[3], 62 | fa[4], fa[5], 63 | fa[6], fa[7], 64 | fa[8], fa[9], 65 | fa[10],fa[11],fa[12]); 66 | if (fabs(f - ff) < FLT_EPSILON) 67 | exit(0); 68 | else 69 | abort(); 70 | } 71 | -------------------------------------------------------------------------------- /m4/ax_append_flag.m4: -------------------------------------------------------------------------------- 1 | # =========================================================================== 2 | # https://www.gnu.org/software/autoconf-archive/ax_append_flag.html 3 | # =========================================================================== 4 | # 5 | # SYNOPSIS 6 | # 7 | # AX_APPEND_FLAG(FLAG, [FLAGS-VARIABLE]) 8 | # 9 | # DESCRIPTION 10 | # 11 | # FLAG is appended to the FLAGS-VARIABLE shell variable, with a space 12 | # added in between. 13 | # 14 | # If FLAGS-VARIABLE is not specified, the current language's flags (e.g. 15 | # CFLAGS) is used. FLAGS-VARIABLE is not changed if it already contains 16 | # FLAG. If FLAGS-VARIABLE is unset in the shell, it is set to exactly 17 | # FLAG. 18 | # 19 | # NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. 20 | # 21 | # LICENSE 22 | # 23 | # Copyright (c) 2008 Guido U. Draheim 24 | # Copyright (c) 2011 Maarten Bosmans 25 | # 26 | # Copying and distribution of this file, with or without modification, are 27 | # permitted in any medium without royalty provided the copyright notice 28 | # and this notice are preserved. This file is offered as-is, without any 29 | # warranty. 30 | 31 | #serial 8 32 | 33 | AC_DEFUN([AX_APPEND_FLAG], 34 | [dnl 35 | AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_SET_IF 36 | AS_VAR_PUSHDEF([FLAGS], [m4_default($2,_AC_LANG_PREFIX[FLAGS])]) 37 | AS_VAR_SET_IF(FLAGS,[ 38 | AS_CASE([" AS_VAR_GET(FLAGS) "], 39 | [*" $1 "*], [AC_RUN_LOG([: FLAGS already contains $1])], 40 | [ 41 | AS_VAR_APPEND(FLAGS,[" $1"]) 42 | AC_RUN_LOG([: FLAGS="$FLAGS"]) 43 | ]) 44 | ], 45 | [ 46 | AS_VAR_SET(FLAGS,[$1]) 47 | AC_RUN_LOG([: FLAGS="$FLAGS"]) 48 | ]) 49 | AS_VAR_POPDEF([FLAGS])dnl 50 | ])dnl AX_APPEND_FLAG 51 | -------------------------------------------------------------------------------- /libffi.map.in: -------------------------------------------------------------------------------- 1 | #define LIBFFI_ASM 2 | #define LIBFFI_H 3 | #include 4 | #include 5 | 6 | /* These version numbers correspond to the libtool-version abi numbers, 7 | not to the libffi release numbers. */ 8 | 9 | LIBFFI_BASE_7.0 { 10 | global: 11 | /* Exported data variables. */ 12 | ffi_type_void; 13 | ffi_type_uint8; 14 | ffi_type_sint8; 15 | ffi_type_uint16; 16 | ffi_type_sint16; 17 | ffi_type_uint32; 18 | ffi_type_sint32; 19 | ffi_type_uint64; 20 | ffi_type_sint64; 21 | ffi_type_float; 22 | ffi_type_double; 23 | ffi_type_longdouble; 24 | ffi_type_pointer; 25 | 26 | /* Exported functions. */ 27 | ffi_call; 28 | ffi_prep_cif; 29 | ffi_prep_cif_var; 30 | 31 | ffi_raw_call; 32 | ffi_ptrarray_to_raw; 33 | ffi_raw_to_ptrarray; 34 | ffi_raw_size; 35 | 36 | ffi_java_raw_call; 37 | ffi_java_ptrarray_to_raw; 38 | ffi_java_raw_to_ptrarray; 39 | ffi_java_raw_size; 40 | 41 | local: 42 | *; 43 | }; 44 | 45 | LIBFFI_BASE_7.1 { 46 | global: 47 | ffi_get_struct_offsets; 48 | } LIBFFI_BASE_7.0; 49 | 50 | #ifdef FFI_TARGET_HAS_COMPLEX_TYPE 51 | LIBFFI_COMPLEX_7.0 { 52 | global: 53 | /* Exported data variables. */ 54 | ffi_type_complex_float; 55 | ffi_type_complex_double; 56 | ffi_type_complex_longdouble; 57 | } LIBFFI_BASE_7.0; 58 | #endif 59 | 60 | #if FFI_CLOSURES 61 | LIBFFI_CLOSURE_7.0 { 62 | global: 63 | ffi_closure_alloc; 64 | ffi_closure_free; 65 | ffi_prep_closure; 66 | ffi_prep_closure_loc; 67 | ffi_prep_raw_closure; 68 | ffi_prep_raw_closure_loc; 69 | ffi_prep_java_raw_closure; 70 | ffi_prep_java_raw_closure_loc; 71 | } LIBFFI_BASE_7.0; 72 | #endif 73 | 74 | #if FFI_GO_CLOSURES 75 | LIBFFI_GO_CLOSURE_7.0 { 76 | global: 77 | ffi_call_go; 78 | ffi_prep_go_closure; 79 | } LIBFFI_CLOSURE_7.0; 80 | #endif 81 | -------------------------------------------------------------------------------- /testsuite/libffi.closures/cls_double_va.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call, closure_call 2 | Purpose: Test doubles passed in variable argument lists. 3 | Limitations: none. 4 | PR: none. 5 | Originator: Blake Chaffin 6/6/2007 */ 6 | 7 | /* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */ 8 | /* { dg-output "" { xfail avr32*-*-* } } */ 9 | /* { dg-output "" { xfail mips-sgi-irix6* } } PR libffi/46660 */ 10 | 11 | #include "ffitest.h" 12 | 13 | static void 14 | cls_double_va_fn(ffi_cif* cif __UNUSED__, void* resp, 15 | void** args, void* userdata __UNUSED__) 16 | { 17 | char* format = *(char**)args[0]; 18 | double doubleValue = *(double*)args[1]; 19 | 20 | *(ffi_arg*)resp = printf(format, doubleValue); 21 | } 22 | 23 | int main (void) 24 | { 25 | ffi_cif cif; 26 | void *code; 27 | ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); 28 | void* args[3]; 29 | ffi_type* arg_types[3]; 30 | 31 | char* format = "%.1f\n"; 32 | double doubleArg = 7; 33 | ffi_arg res = 0; 34 | 35 | arg_types[0] = &ffi_type_pointer; 36 | arg_types[1] = &ffi_type_double; 37 | arg_types[2] = NULL; 38 | 39 | /* This printf call is variadic */ 40 | CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2, &ffi_type_sint, 41 | arg_types) == FFI_OK); 42 | 43 | args[0] = &format; 44 | args[1] = &doubleArg; 45 | args[2] = NULL; 46 | 47 | ffi_call(&cif, FFI_FN(printf), &res, args); 48 | /* { dg-output "7.0" } */ 49 | printf("res: %d\n", (int) res); 50 | /* { dg-output "\nres: 4" } */ 51 | 52 | CHECK(ffi_prep_closure_loc(pcl, &cif, cls_double_va_fn, NULL, 53 | code) == FFI_OK); 54 | 55 | res = ((int(*)(char*, ...))(code))(format, doubleArg); 56 | /* { dg-output "\n7.0" } */ 57 | printf("res: %d\n", (int) res); 58 | /* { dg-output "\nres: 4" } */ 59 | 60 | exit(0); 61 | } 62 | -------------------------------------------------------------------------------- /testsuite/libffi.call/float3.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check float arguments with different orders. 3 | Limitations: none. 4 | PR: none. 5 | Originator: From the original ffitest.c */ 6 | 7 | /* { dg-do run } */ 8 | 9 | #include "ffitest.h" 10 | #include "float.h" 11 | 12 | #include 13 | 14 | static double floating_1(float a, double b, long double c) 15 | { 16 | return (double) a + b + (double) c; 17 | } 18 | 19 | static double floating_2(long double a, double b, float c) 20 | { 21 | return (double) a + b + (double) c; 22 | } 23 | 24 | int main (void) 25 | { 26 | ffi_cif cif; 27 | ffi_type *args[MAX_ARGS]; 28 | void *values[MAX_ARGS]; 29 | double rd; 30 | 31 | float f; 32 | double d; 33 | long double ld; 34 | 35 | args[0] = &ffi_type_float; 36 | values[0] = &f; 37 | args[1] = &ffi_type_double; 38 | values[1] = &d; 39 | args[2] = &ffi_type_longdouble; 40 | values[2] = &ld; 41 | 42 | /* Initialize the cif */ 43 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, 44 | &ffi_type_double, args) == FFI_OK); 45 | 46 | f = 3.14159; 47 | d = (double)1.0/(double)3.0; 48 | ld = 2.71828182846L; 49 | 50 | floating_1 (f, d, ld); 51 | 52 | ffi_call(&cif, FFI_FN(floating_1), &rd, values); 53 | 54 | CHECK(fabs(rd - floating_1(f, d, ld)) < DBL_EPSILON); 55 | 56 | args[0] = &ffi_type_longdouble; 57 | values[0] = &ld; 58 | args[1] = &ffi_type_double; 59 | values[1] = &d; 60 | args[2] = &ffi_type_float; 61 | values[2] = &f; 62 | 63 | /* Initialize the cif */ 64 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, 65 | &ffi_type_double, args) == FFI_OK); 66 | 67 | floating_2 (ld, d, f); 68 | 69 | ffi_call(&cif, FFI_FN(floating_2), &rd, values); 70 | 71 | CHECK(fabs(rd - floating_2(ld, d, f)) < DBL_EPSILON); 72 | 73 | exit (0); 74 | } 75 | -------------------------------------------------------------------------------- /src/bfin/ffitarget.h: -------------------------------------------------------------------------------- 1 | /* ----------------------------------------------------------------------- 2 | ffitarget.h - Copyright (c) 2012 Alexandre K. I. de Mendonca 3 | 4 | Blackfin Foreign Function Interface 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files (the 8 | ``Software''), to deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included 15 | in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | ----------------------------------------------------------------------- */ 26 | 27 | #ifndef LIBFFI_TARGET_H 28 | #define LIBFFI_TARGET_H 29 | 30 | #ifndef LIBFFI_ASM 31 | typedef unsigned long ffi_arg; 32 | typedef signed long ffi_sarg; 33 | 34 | typedef enum ffi_abi { 35 | FFI_FIRST_ABI = 0, 36 | FFI_SYSV, 37 | FFI_LAST_ABI, 38 | FFI_DEFAULT_ABI = FFI_SYSV 39 | } ffi_abi; 40 | #endif 41 | 42 | #endif 43 | 44 | -------------------------------------------------------------------------------- /src/m88k/ffitarget.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013 Miodrag Vallat. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining 5 | * a copy of this software and associated documentation files (the 6 | * ``Software''), to deal in the Software without restriction, including 7 | * without limitation the rights to use, copy, modify, merge, publish, 8 | * distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to 10 | * the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included 13 | * in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 19 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 20 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 21 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | /* 25 | * m88k Foreign Function Interface 26 | */ 27 | 28 | #ifndef LIBFFI_TARGET_H 29 | #define LIBFFI_TARGET_H 30 | 31 | #ifndef LIBFFI_ASM 32 | typedef unsigned long ffi_arg; 33 | typedef signed long ffi_sarg; 34 | 35 | typedef enum ffi_abi { 36 | FFI_FIRST_ABI = 0, 37 | FFI_OBSD, 38 | FFI_DEFAULT_ABI = FFI_OBSD, 39 | FFI_LAST_ABI = FFI_DEFAULT_ABI + 1 40 | } ffi_abi; 41 | #endif 42 | 43 | /* ---- Definitions for closures ----------------------------------------- */ 44 | 45 | #define FFI_CLOSURES 1 46 | #define FFI_TRAMPOLINE_SIZE 0x14 47 | #define FFI_NATIVE_RAW_API 0 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /src/vax/ffitarget.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013 Miodrag Vallat. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining 5 | * a copy of this software and associated documentation files (the 6 | * ``Software''), to deal in the Software without restriction, including 7 | * without limitation the rights to use, copy, modify, merge, publish, 8 | * distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to 10 | * the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included 13 | * in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 19 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 20 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 21 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | /* 25 | * vax Foreign Function Interface 26 | */ 27 | 28 | #ifndef LIBFFI_TARGET_H 29 | #define LIBFFI_TARGET_H 30 | 31 | #ifndef LIBFFI_ASM 32 | typedef unsigned long ffi_arg; 33 | typedef signed long ffi_sarg; 34 | 35 | typedef enum ffi_abi { 36 | FFI_FIRST_ABI = 0, 37 | FFI_ELFBSD, 38 | FFI_DEFAULT_ABI = FFI_ELFBSD, 39 | FFI_LAST_ABI = FFI_DEFAULT_ABI + 1 40 | } ffi_abi; 41 | #endif 42 | 43 | /* ---- Definitions for closures ----------------------------------------- */ 44 | 45 | #define FFI_CLOSURES 1 46 | #define FFI_TRAMPOLINE_SIZE 15 47 | #define FFI_NATIVE_RAW_API 0 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /testsuite/libffi.closures/cls_longdouble_va.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call, closure_call 2 | Purpose: Test long doubles passed in variable argument lists. 3 | Limitations: none. 4 | PR: none. 5 | Originator: Blake Chaffin 6/6/2007 */ 6 | 7 | /* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */ 8 | /* { dg-output "" { xfail avr32*-*-* x86_64-*-mingw* } } */ 9 | /* { dg-output "" { xfail mips-sgi-irix6* } } PR libffi/46660 */ 10 | 11 | #include "ffitest.h" 12 | 13 | static void 14 | cls_longdouble_va_fn(ffi_cif* cif __UNUSED__, void* resp, 15 | void** args, void* userdata __UNUSED__) 16 | { 17 | char* format = *(char**)args[0]; 18 | long double ldValue = *(long double*)args[1]; 19 | 20 | *(ffi_arg*)resp = printf(format, ldValue); 21 | } 22 | 23 | int main (void) 24 | { 25 | ffi_cif cif; 26 | void *code; 27 | ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); 28 | void* args[3]; 29 | ffi_type* arg_types[3]; 30 | 31 | char* format = "%.1Lf\n"; 32 | long double ldArg = 7; 33 | ffi_arg res = 0; 34 | 35 | arg_types[0] = &ffi_type_pointer; 36 | arg_types[1] = &ffi_type_longdouble; 37 | arg_types[2] = NULL; 38 | 39 | /* This printf call is variadic */ 40 | CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2, &ffi_type_sint, 41 | arg_types) == FFI_OK); 42 | 43 | args[0] = &format; 44 | args[1] = &ldArg; 45 | args[2] = NULL; 46 | 47 | ffi_call(&cif, FFI_FN(printf), &res, args); 48 | /* { dg-output "7.0" } */ 49 | printf("res: %d\n", (int) res); 50 | /* { dg-output "\nres: 4" } */ 51 | 52 | CHECK(ffi_prep_closure_loc(pcl, &cif, cls_longdouble_va_fn, NULL, 53 | code) == FFI_OK); 54 | 55 | res = ((int(*)(char*, ...))(code))(format, ldArg); 56 | /* { dg-output "\n7.0" } */ 57 | printf("res: %d\n", (int) res); 58 | /* { dg-output "\nres: 4" } */ 59 | 60 | exit(0); 61 | } 62 | -------------------------------------------------------------------------------- /m4/ax_configure_args.m4: -------------------------------------------------------------------------------- 1 | # =========================================================================== 2 | # https://www.gnu.org/software/autoconf-archive/ax_configure_args.html 3 | # =========================================================================== 4 | # 5 | # SYNOPSIS 6 | # 7 | # AX_CONFIGURE_ARGS 8 | # 9 | # DESCRIPTION 10 | # 11 | # Helper macro for AX_ENABLE_BUILDDIR. 12 | # 13 | # The traditional way of starting a subdir-configure is running the script 14 | # with ${1+"$@"} but since autoconf 2.60 this is broken. Instead we have 15 | # to rely on eval'ing $ac_configure_args however some old autoconf 16 | # versions do not provide that. To ensure maximum portability of autoconf 17 | # extension macros this helper can be AC_REQUIRE'd so that 18 | # $ac_configure_args will always be present. 19 | # 20 | # Sadly, the traditional "exec $SHELL" of the enable_builddir macros is 21 | # spoiled now and must be replaced by "eval + exit $?". 22 | # 23 | # Example: 24 | # 25 | # AC_DEFUN([AX_ENABLE_SUBDIR],[dnl 26 | # AC_REQUIRE([AX_CONFIGURE_ARGS])dnl 27 | # eval $SHELL $ac_configure_args || exit $? 28 | # ...]) 29 | # 30 | # LICENSE 31 | # 32 | # Copyright (c) 2008 Guido U. Draheim 33 | # 34 | # Copying and distribution of this file, with or without modification, are 35 | # permitted in any medium without royalty provided the copyright notice 36 | # and this notice are preserved. This file is offered as-is, without any 37 | # warranty. 38 | 39 | #serial 14 40 | 41 | AC_DEFUN([AX_CONFIGURE_ARGS],[ 42 | # [$]@ is unusable in 2.60+ but earlier autoconf had no ac_configure_args 43 | if test "${ac_configure_args+set}" != "set" ; then 44 | ac_configure_args= 45 | for ac_arg in ${1+"[$]@"}; do 46 | ac_configure_args="$ac_configure_args '$ac_arg'" 47 | done 48 | fi 49 | ]) 50 | -------------------------------------------------------------------------------- /testsuite/libffi.complex/cls_complex_struct.inc: -------------------------------------------------------------------------------- 1 | /* -*-c-*- */ 2 | #include "ffitest.h" 3 | #include 4 | 5 | typedef struct Cs { 6 | _Complex T_C_TYPE x; 7 | _Complex T_C_TYPE y; 8 | } Cs; 9 | 10 | Cs gc; 11 | 12 | void 13 | closure_test_fn(Cs p) 14 | { 15 | printf("%.1f,%.1fi %.1f,%.1fi\n", 16 | T_CONV creal (p.x), T_CONV cimag (p.x), 17 | T_CONV creal (p.y), T_CONV cimag (p.y)); 18 | gc = p; 19 | } 20 | 21 | void 22 | closure_test_gn(ffi_cif* cif __UNUSED__, void* resp __UNUSED__, 23 | void** args, void* userdata __UNUSED__) 24 | { 25 | closure_test_fn(*(Cs*)args[0]); 26 | } 27 | 28 | int main(int argc __UNUSED__, char** argv __UNUSED__) 29 | { 30 | ffi_cif cif; 31 | 32 | void *code; 33 | ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); 34 | ffi_type *cl_arg_types[1]; 35 | 36 | ffi_type ts1_type; 37 | ffi_type* ts1_type_elements[4]; 38 | 39 | Cs arg = { 1.0 + 11.0 * I, 2.0 + 22.0 * I}; 40 | 41 | ts1_type.size = 0; 42 | ts1_type.alignment = 0; 43 | ts1_type.type = FFI_TYPE_STRUCT; 44 | ts1_type.elements = ts1_type_elements; 45 | 46 | ts1_type_elements[0] = &T_FFI_TYPE; 47 | ts1_type_elements[1] = &T_FFI_TYPE; 48 | ts1_type_elements[2] = NULL; 49 | 50 | cl_arg_types[0] = &ts1_type; 51 | 52 | /* Initialize the cif */ 53 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 54 | &ffi_type_void, cl_arg_types) == FFI_OK); 55 | 56 | CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_gn, NULL, code) == FFI_OK); 57 | 58 | gc.x = 0.0 + 0.0 * I; 59 | gc.y = 0.0 + 0.0 * I; 60 | ((void*(*)(Cs))(code))(arg); 61 | /* { dg-output "1.0,11.0i 2.0,22.0i\n" } */ 62 | CHECK (gc.x == arg.x && gc.y == arg.y); 63 | 64 | gc.x = 0.0 + 0.0 * I; 65 | gc.y = 0.0 + 0.0 * I; 66 | closure_test_fn(arg); 67 | /* { dg-output "1.0,11.0i 2.0,22.0i\n" } */ 68 | CHECK (gc.x == arg.x && gc.y == arg.y); 69 | 70 | return 0; 71 | } 72 | -------------------------------------------------------------------------------- /testsuite/libffi.call/many_mixed.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check return value double, with many arguments 3 | Limitations: none. 4 | PR: none. 5 | Originator: From the original ffitest.c */ 6 | 7 | /* { dg-do run } */ 8 | #include "ffitest.h" 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | static double many(double f1, 15 | double f2, 16 | long int i1, 17 | double f3, 18 | double f4, 19 | long int i2, 20 | double f5, 21 | double f6, 22 | long int i3, 23 | double f7, 24 | double f8, 25 | long int i4, 26 | double f9, 27 | double f10, 28 | long int i5, 29 | double f11, 30 | double f12, 31 | long int i6, 32 | double f13) 33 | { 34 | return ((double) (i1 + i2 + i3 + i4 + i5 + i6) + (f1/f2+f3/f4+f5/f6+f7/f8+f9/f10+f11/f12) * f13); 35 | } 36 | 37 | int main (void) 38 | { 39 | ffi_cif cif; 40 | ffi_type *args[19]; 41 | void *values[19]; 42 | double fa[19]; 43 | long int la[19]; 44 | double f, ff; 45 | int i; 46 | 47 | for (i = 0; i < 19; i++) 48 | { 49 | if( (i - 2) % 3 == 0) { 50 | args[i] = &ffi_type_slong; 51 | la[i] = (long int) i; 52 | values[i] = &la[i]; 53 | } 54 | else { 55 | args[i] = &ffi_type_double; 56 | fa[i] = (double) i; 57 | values[i] = &fa[i]; 58 | } 59 | } 60 | 61 | /* Initialize the cif */ 62 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 19, 63 | &ffi_type_double, args) == FFI_OK); 64 | 65 | ffi_call(&cif, FFI_FN(many), &f, values); 66 | 67 | ff = many(fa[0], fa[1], la[2], 68 | fa[3], fa[4], la[5], 69 | fa[6], fa[7], la[8], 70 | fa[9], fa[10], la[11], 71 | fa[12], fa[13], la[14], 72 | fa[15], fa[16], la[17], 73 | fa[18]); 74 | if (fabs(f - ff) < FLT_EPSILON) 75 | exit(0); 76 | else 77 | abort(); 78 | } 79 | -------------------------------------------------------------------------------- /testsuite/libffi.call/call.exp: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2003, 2006, 2009, 2010, 2014, 2019 Free Software Foundation, Inc. 2 | 3 | # This program is free software; you can redistribute it and/or modify 4 | # it under the terms of the GNU General Public License as published by 5 | # the Free Software Foundation; either version 3 of the License, or 6 | # (at your option) any later version. 7 | # 8 | # This program is distributed in the hope that it will be useful, 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | # GNU General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License 14 | # along with this program; see the file COPYING3. If not see 15 | # . 16 | 17 | dg-init 18 | libffi-init 19 | 20 | global srcdir subdir 21 | 22 | if { [string match $compiler_vendor "microsoft"] } { 23 | # -wd4005 macro redefinition 24 | # -wd4244 implicit conversion to type of smaller size 25 | # -wd4305 truncation to smaller type 26 | # -wd4477 printf %lu of uintptr_t 27 | # -wd4312 implicit conversion to type of greater size 28 | # -wd4311 pointer truncation to unsigned long 29 | # -EHsc C++ Exception Handling (no SEH exceptions) 30 | set additional_options "-wd4005 -wd4244 -wd4305 -wd4477 -wd4312 -wd4311 -EHsc"; 31 | } else { 32 | set additional_options ""; 33 | } 34 | 35 | set tlist [lsort [glob -nocomplain -- $srcdir/$subdir/*.c]] 36 | 37 | run-many-tests $tlist $additional_options 38 | 39 | set tlist [lsort [glob -nocomplain -- $srcdir/$subdir/*.cc]] 40 | 41 | # No C++ for or1k 42 | if { [istarget "or1k-*-*"] } { 43 | foreach test $tlist { 44 | unsupported "$test" 45 | } 46 | } else { 47 | run-many-tests $tlist $additional_options 48 | } 49 | 50 | dg-finish 51 | 52 | # Local Variables: 53 | # tcl-indent-level:4 54 | # End: 55 | -------------------------------------------------------------------------------- /testsuite/libffi.call/struct7.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check structures. 3 | Limitations: none. 4 | PR: none. 5 | Originator: From the original ffitest.c */ 6 | 7 | /* { dg-do run } */ 8 | #include "ffitest.h" 9 | typedef struct 10 | { 11 | float f1; 12 | float f2; 13 | double d; 14 | } test_structure_7; 15 | 16 | static test_structure_7 ABI_ATTR struct7 (test_structure_7 ts) 17 | { 18 | ts.f1 += 1; 19 | ts.f2 += 1; 20 | ts.d += 1; 21 | 22 | return ts; 23 | } 24 | 25 | int main (void) 26 | { 27 | ffi_cif cif; 28 | ffi_type *args[MAX_ARGS]; 29 | void *values[MAX_ARGS]; 30 | ffi_type ts7_type; 31 | ffi_type *ts7_type_elements[4]; 32 | 33 | test_structure_7 ts7_arg; 34 | 35 | /* This is a hack to get a properly aligned result buffer */ 36 | test_structure_7 *ts7_result = 37 | (test_structure_7 *) malloc (sizeof(test_structure_7)); 38 | 39 | ts7_type.size = 0; 40 | ts7_type.alignment = 0; 41 | ts7_type.type = FFI_TYPE_STRUCT; 42 | ts7_type.elements = ts7_type_elements; 43 | ts7_type_elements[0] = &ffi_type_float; 44 | ts7_type_elements[1] = &ffi_type_float; 45 | ts7_type_elements[2] = &ffi_type_double; 46 | ts7_type_elements[3] = NULL; 47 | 48 | args[0] = &ts7_type; 49 | values[0] = &ts7_arg; 50 | 51 | /* Initialize the cif */ 52 | CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ts7_type, args) == FFI_OK); 53 | 54 | ts7_arg.f1 = 5.55f; 55 | ts7_arg.f2 = 55.5f; 56 | ts7_arg.d = 6.66; 57 | 58 | printf ("%g\n", ts7_arg.f1); 59 | printf ("%g\n", ts7_arg.f2); 60 | printf ("%g\n", ts7_arg.d); 61 | 62 | ffi_call(&cif, FFI_FN(struct7), ts7_result, values); 63 | 64 | printf ("%g\n", ts7_result->f1); 65 | printf ("%g\n", ts7_result->f2); 66 | printf ("%g\n", ts7_result->d); 67 | 68 | CHECK(ts7_result->f1 == 5.55f + 1); 69 | CHECK(ts7_result->f2 == 55.5f + 1); 70 | CHECK(ts7_result->d == 6.66 + 1); 71 | 72 | free (ts7_result); 73 | exit(0); 74 | } 75 | -------------------------------------------------------------------------------- /testsuite/libffi.closures/cls_many_mixed_float_double.c: -------------------------------------------------------------------------------- 1 | /* Area: closure_call 2 | Purpose: Check register allocation for closure calls with many float and double arguments 3 | Limitations: none. 4 | PR: none. 5 | Originator: */ 6 | 7 | /* { dg-do run } */ 8 | #include "ffitest.h" 9 | #include 10 | #include 11 | 12 | #define NARGS 16 13 | 14 | static void cls_mixed_float_double_fn(ffi_cif* cif , void* ret, void** args, 15 | void* userdata __UNUSED__) 16 | { 17 | double r = 0; 18 | unsigned int i; 19 | double t; 20 | for(i=0; i < cif->nargs; i++) 21 | { 22 | if(cif->arg_types[i] == &ffi_type_double) { 23 | t = *(((double**)(args))[i]); 24 | } else { 25 | t = *(((float**)(args))[i]); 26 | } 27 | r += t; 28 | } 29 | *((double*)ret) = r; 30 | } 31 | typedef double (*cls_mixed)(double, float, double, double, double, double, double, float, float, double, float, float); 32 | 33 | int main (void) 34 | { 35 | ffi_cif cif; 36 | ffi_closure *closure; 37 | void* code; 38 | ffi_type *argtypes[12] = {&ffi_type_double, &ffi_type_float, &ffi_type_double, 39 | &ffi_type_double, &ffi_type_double, &ffi_type_double, 40 | &ffi_type_double, &ffi_type_float, &ffi_type_float, 41 | &ffi_type_double, &ffi_type_float, &ffi_type_float}; 42 | 43 | 44 | closure = ffi_closure_alloc(sizeof(ffi_closure), (void**)&code); 45 | if(closure ==NULL) 46 | abort(); 47 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 12, &ffi_type_double, argtypes) == FFI_OK); 48 | CHECK(ffi_prep_closure_loc(closure, &cif, cls_mixed_float_double_fn, NULL, code) == FFI_OK); 49 | double ret = ((cls_mixed)code)(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2); 50 | ffi_closure_free(closure); 51 | if(fabs(ret - 7.8) < FLT_EPSILON) 52 | exit(0); 53 | else 54 | abort(); 55 | } 56 | -------------------------------------------------------------------------------- /testsuite/libffi.closures/testclosure.c: -------------------------------------------------------------------------------- 1 | /* Area: closure_call 2 | Purpose: Check return value float. 3 | Limitations: none. 4 | PR: 41908. 5 | Originator: 20091102 */ 6 | 7 | /* { dg-do run } */ 8 | #include "ffitest.h" 9 | 10 | typedef struct cls_struct_combined { 11 | float a; 12 | float b; 13 | float c; 14 | float d; 15 | } cls_struct_combined; 16 | 17 | void cls_struct_combined_fn(struct cls_struct_combined arg) 18 | { 19 | printf("%g %g %g %g\n", 20 | arg.a, arg.b, 21 | arg.c, arg.d); 22 | fflush(stdout); 23 | } 24 | 25 | static void 26 | cls_struct_combined_gn(ffi_cif* cif __UNUSED__, void* resp __UNUSED__, 27 | void** args, void* userdata __UNUSED__) 28 | { 29 | struct cls_struct_combined a0; 30 | 31 | a0 = *(struct cls_struct_combined*)(args[0]); 32 | 33 | cls_struct_combined_fn(a0); 34 | } 35 | 36 | 37 | int main (void) 38 | { 39 | ffi_cif cif; 40 | void *code; 41 | ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); 42 | ffi_type* cls_struct_fields0[5]; 43 | ffi_type cls_struct_type0; 44 | ffi_type* dbl_arg_types[5]; 45 | 46 | struct cls_struct_combined g_dbl = {4.0, 5.0, 1.0, 8.0}; 47 | 48 | cls_struct_type0.size = 0; 49 | cls_struct_type0.alignment = 0; 50 | cls_struct_type0.type = FFI_TYPE_STRUCT; 51 | cls_struct_type0.elements = cls_struct_fields0; 52 | 53 | cls_struct_fields0[0] = &ffi_type_float; 54 | cls_struct_fields0[1] = &ffi_type_float; 55 | cls_struct_fields0[2] = &ffi_type_float; 56 | cls_struct_fields0[3] = &ffi_type_float; 57 | cls_struct_fields0[4] = NULL; 58 | 59 | dbl_arg_types[0] = &cls_struct_type0; 60 | dbl_arg_types[1] = NULL; 61 | 62 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ffi_type_void, 63 | dbl_arg_types) == FFI_OK); 64 | 65 | CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_combined_gn, NULL, code) == FFI_OK); 66 | 67 | ((void(*)(cls_struct_combined)) (code))(g_dbl); 68 | /* { dg-output "4 5 1 8" } */ 69 | exit(0); 70 | } 71 | -------------------------------------------------------------------------------- /testsuite/libffi.closures/cls_multi_schar.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call, closure_call 2 | Purpose: Check passing of multiple signed char values. 3 | Limitations: none. 4 | PR: PR13221. 5 | Originator: 20031129 */ 6 | 7 | /* { dg-do run } */ 8 | #include "ffitest.h" 9 | 10 | signed char test_func_fn(signed char a1, signed char a2) 11 | { 12 | signed char result; 13 | 14 | result = a1 + a2; 15 | 16 | printf("%d %d: %d\n", a1, a2, result); 17 | 18 | return result; 19 | 20 | } 21 | 22 | static void test_func_gn(ffi_cif *cif __UNUSED__, void *rval, void **avals, 23 | void *data __UNUSED__) 24 | { 25 | signed char a1, a2; 26 | 27 | a1 = *(signed char *)avals[0]; 28 | a2 = *(signed char *)avals[1]; 29 | 30 | *(ffi_arg *)rval = test_func_fn(a1, a2); 31 | 32 | } 33 | 34 | typedef signed char (*test_type)(signed char, signed char); 35 | 36 | int main (void) 37 | { 38 | ffi_cif cif; 39 | void *code; 40 | ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); 41 | void * args_dbl[3]; 42 | ffi_type * cl_arg_types[3]; 43 | ffi_arg res_call; 44 | signed char a, b, res_closure; 45 | 46 | a = 2; 47 | b = 125; 48 | 49 | args_dbl[0] = &a; 50 | args_dbl[1] = &b; 51 | args_dbl[2] = NULL; 52 | 53 | cl_arg_types[0] = &ffi_type_schar; 54 | cl_arg_types[1] = &ffi_type_schar; 55 | cl_arg_types[2] = NULL; 56 | 57 | /* Initialize the cif */ 58 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, 59 | &ffi_type_schar, cl_arg_types) == FFI_OK); 60 | 61 | ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl); 62 | /* { dg-output "2 125: 127" } */ 63 | printf("res: %d\n", (signed char)res_call); 64 | /* { dg-output "\nres: 127" } */ 65 | 66 | CHECK(ffi_prep_closure_loc(pcl, &cif, test_func_gn, NULL, code) == FFI_OK); 67 | 68 | res_closure = (*((test_type)code))(2, 125); 69 | /* { dg-output "\n2 125: 127" } */ 70 | printf("res: %d\n", res_closure); 71 | /* { dg-output "\nres: 127" } */ 72 | 73 | exit(0); 74 | } 75 | -------------------------------------------------------------------------------- /src/nios2/ffitarget.h: -------------------------------------------------------------------------------- 1 | /* libffi target includes for Altera Nios II. 2 | 3 | Copyright (c) 2013 Mentor Graphics. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | ``Software''), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 23 | 24 | 25 | #ifndef LIBFFI_TARGET_H 26 | #define LIBFFI_TARGET_H 27 | 28 | #ifndef LIBFFI_H 29 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." 30 | #endif 31 | 32 | #ifndef LIBFFI_ASM 33 | typedef unsigned long ffi_arg; 34 | typedef signed long ffi_sarg; 35 | 36 | typedef enum ffi_abi { 37 | FFI_FIRST_ABI = 0, 38 | FFI_SYSV, 39 | FFI_LAST_ABI, 40 | FFI_DEFAULT_ABI = FFI_SYSV 41 | } ffi_abi; 42 | #endif 43 | 44 | /* Structures have a 4-byte alignment even if all the fields have lesser 45 | alignment requirements. */ 46 | #define FFI_AGGREGATE_ALIGNMENT 4 47 | 48 | #define FFI_CLOSURES 1 49 | #define FFI_TRAMPOLINE_SIZE 28 /* 7 instructions */ 50 | #define FFI_NATIVE_RAW_API 0 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /testsuite/libffi.closures/cls_multi_sshort.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call, closure_call 2 | Purpose: Check passing of multiple signed short values. 3 | Limitations: none. 4 | PR: PR13221. 5 | Originator: 20031129 */ 6 | 7 | /* { dg-do run } */ 8 | #include "ffitest.h" 9 | 10 | signed short test_func_fn(signed short a1, signed short a2) 11 | { 12 | signed short result; 13 | 14 | result = a1 + a2; 15 | 16 | printf("%d %d: %d\n", a1, a2, result); 17 | 18 | return result; 19 | 20 | } 21 | 22 | static void test_func_gn(ffi_cif *cif __UNUSED__, void *rval, void **avals, 23 | void *data __UNUSED__) 24 | { 25 | signed short a1, a2; 26 | 27 | a1 = *(signed short *)avals[0]; 28 | a2 = *(signed short *)avals[1]; 29 | 30 | *(ffi_arg *)rval = test_func_fn(a1, a2); 31 | 32 | } 33 | 34 | typedef signed short (*test_type)(signed short, signed short); 35 | 36 | int main (void) 37 | { 38 | ffi_cif cif; 39 | void *code; 40 | ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); 41 | void * args_dbl[3]; 42 | ffi_type * cl_arg_types[3]; 43 | ffi_arg res_call; 44 | unsigned short a, b, res_closure; 45 | 46 | a = 2; 47 | b = 32765; 48 | 49 | args_dbl[0] = &a; 50 | args_dbl[1] = &b; 51 | args_dbl[2] = NULL; 52 | 53 | cl_arg_types[0] = &ffi_type_sshort; 54 | cl_arg_types[1] = &ffi_type_sshort; 55 | cl_arg_types[2] = NULL; 56 | 57 | /* Initialize the cif */ 58 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, 59 | &ffi_type_sshort, cl_arg_types) == FFI_OK); 60 | 61 | ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl); 62 | /* { dg-output "2 32765: 32767" } */ 63 | printf("res: %d\n", (unsigned short)res_call); 64 | /* { dg-output "\nres: 32767" } */ 65 | 66 | CHECK(ffi_prep_closure_loc(pcl, &cif, test_func_gn, NULL, code) == FFI_OK); 67 | 68 | res_closure = (*((test_type)code))(2, 32765); 69 | /* { dg-output "\n2 32765: 32767" } */ 70 | printf("res: %d\n", res_closure); 71 | /* { dg-output "\nres: 32767" } */ 72 | 73 | exit(0); 74 | } 75 | -------------------------------------------------------------------------------- /src/microblaze/ffitarget.h: -------------------------------------------------------------------------------- 1 | /* ----------------------------------------------------------------------- 2 | ffitarget.h - Copyright (c) 2012, 2013 Xilinx, Inc 3 | 4 | Target configuration macros for MicroBlaze. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files (the 8 | ``Software''), to deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included 15 | in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | ----------------------------------------------------------------------- */ 26 | 27 | #ifndef LIBFFI_TARGET_H 28 | #define LIBFFI_TARGET_H 29 | 30 | #ifndef LIBFFI_H 31 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." 32 | #endif 33 | 34 | #ifndef LIBFFI_ASM 35 | typedef unsigned long ffi_arg; 36 | typedef signed long ffi_sarg; 37 | 38 | typedef enum ffi_abi { 39 | FFI_FIRST_ABI = 0, 40 | FFI_SYSV, 41 | FFI_LAST_ABI, 42 | FFI_DEFAULT_ABI = FFI_SYSV 43 | } ffi_abi; 44 | #endif 45 | 46 | /* Definitions for closures */ 47 | 48 | #define FFI_CLOSURES 1 49 | #define FFI_NATIVE_RAW_API 0 50 | 51 | #define FFI_TRAMPOLINE_SIZE (4*8) 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /testsuite/libffi.closures/cls_multi_ushort.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call, closure_call 2 | Purpose: Check passing of multiple unsigned short values. 3 | Limitations: none. 4 | PR: PR13221. 5 | Originator: 20031129 */ 6 | 7 | /* { dg-do run } */ 8 | #include "ffitest.h" 9 | 10 | unsigned short test_func_fn(unsigned short a1, unsigned short a2) 11 | { 12 | unsigned short result; 13 | 14 | result = a1 + a2; 15 | 16 | printf("%d %d: %d\n", a1, a2, result); 17 | 18 | return result; 19 | 20 | } 21 | 22 | static void test_func_gn(ffi_cif *cif __UNUSED__, void *rval, void **avals, 23 | void *data __UNUSED__) 24 | { 25 | unsigned short a1, a2; 26 | 27 | a1 = *(unsigned short *)avals[0]; 28 | a2 = *(unsigned short *)avals[1]; 29 | 30 | *(ffi_arg *)rval = test_func_fn(a1, a2); 31 | 32 | } 33 | 34 | typedef unsigned short (*test_type)(unsigned short, unsigned short); 35 | 36 | int main (void) 37 | { 38 | ffi_cif cif; 39 | void *code; 40 | ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); 41 | void * args_dbl[3]; 42 | ffi_type * cl_arg_types[3]; 43 | ffi_arg res_call; 44 | unsigned short a, b, res_closure; 45 | 46 | a = 2; 47 | b = 32765; 48 | 49 | args_dbl[0] = &a; 50 | args_dbl[1] = &b; 51 | args_dbl[2] = NULL; 52 | 53 | cl_arg_types[0] = &ffi_type_ushort; 54 | cl_arg_types[1] = &ffi_type_ushort; 55 | cl_arg_types[2] = NULL; 56 | 57 | /* Initialize the cif */ 58 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, 59 | &ffi_type_ushort, cl_arg_types) == FFI_OK); 60 | 61 | ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl); 62 | /* { dg-output "2 32765: 32767" } */ 63 | printf("res: %d\n", (unsigned short)res_call); 64 | /* { dg-output "\nres: 32767" } */ 65 | 66 | CHECK(ffi_prep_closure_loc(pcl, &cif, test_func_gn, NULL, code) == FFI_OK); 67 | 68 | res_closure = (*((test_type)code))(2, 32765); 69 | /* { dg-output "\n2 32765: 32767" } */ 70 | printf("res: %d\n", res_closure); 71 | /* { dg-output "\nres: 32767" } */ 72 | 73 | exit(0); 74 | } 75 | -------------------------------------------------------------------------------- /testsuite/lib/wrapper.exp: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2004, 2007 Free Software Foundation, Inc. 2 | 3 | # This program is free software; you can redistribute it and/or modify 4 | # it under the terms of the GNU General Public License as published by 5 | # the Free Software Foundation; either version 3 of the License, or 6 | # (at your option) any later version. 7 | # 8 | # This program is distributed in the hope that it will be useful, 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | # GNU General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License 14 | # along with GCC; see the file COPYING3. If not see 15 | # . 16 | 17 | # This file contains GCC-specifics for status wrappers for test programs. 18 | 19 | # ${tool}_maybe_build_wrapper -- Build wrapper object if the target 20 | # needs it. FILENAME is the path to the wrapper file. If there are 21 | # additional arguments, they are command-line options to provide to 22 | # the compiler when compiling FILENAME. 23 | 24 | proc ${tool}_maybe_build_wrapper { filename args } { 25 | global gluefile wrap_flags 26 | 27 | if { [target_info needs_status_wrapper] != "" \ 28 | && [target_info needs_status_wrapper] != "0" \ 29 | && ![info exists gluefile] } { 30 | set saved_wrap_compile_flags [target_info wrap_compile_flags] 31 | set flags [join $args " "] 32 | # The wrapper code may contain code that gcc objects on. This 33 | # became true for dejagnu-1.4.4. The set of warnings and code 34 | # that gcc objects on may change, so just make sure -w is always 35 | # passed to turn off all warnings. 36 | set_currtarget_info wrap_compile_flags \ 37 | "$saved_wrap_compile_flags -w $flags" 38 | set result [build_wrapper $filename] 39 | set_currtarget_info wrap_compile_flags "$saved_wrap_compile_flags" 40 | if { $result != "" } { 41 | set gluefile [lindex $result 0] 42 | set wrap_flags [lindex $result 1] 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /testsuite/libffi.closures/cls_many_mixed_args.c: -------------------------------------------------------------------------------- 1 | /* Area: closure_call 2 | Purpose: Check closures called with many args of mixed types 3 | Limitations: none. 4 | PR: none. 5 | Originator: */ 6 | 7 | /* { dg-do run } */ 8 | #include "ffitest.h" 9 | #include 10 | #include 11 | 12 | #define NARGS 16 13 | 14 | static void cls_ret_double_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, 15 | void* userdata __UNUSED__) 16 | { 17 | int i; 18 | double r = 0; 19 | double t; 20 | for(i = 0; i < NARGS; i++) 21 | { 22 | if(i == 4 || i == 9 || i == 11 || i == 13 || i == 15) 23 | { 24 | t = *(long int *)args[i]; 25 | CHECK(t == i+1); 26 | } 27 | else 28 | { 29 | t = *(double *)args[i]; 30 | CHECK(fabs(t - ((i+1) * 0.1)) < FLT_EPSILON); 31 | } 32 | r += t; 33 | } 34 | *(double *)resp = r; 35 | } 36 | typedef double (*cls_ret_double)(double, double, double, double, long int, 37 | double, double, double, double, long int, double, long int, double, long int, 38 | double, long int); 39 | 40 | int main (void) 41 | { 42 | ffi_cif cif; 43 | void *code; 44 | ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); 45 | ffi_type * cl_arg_types[NARGS]; 46 | double res; 47 | int i; 48 | double expected = 64.9; 49 | 50 | for(i = 0; i < NARGS; i++) 51 | { 52 | if(i == 4 || i == 9 || i == 11 || i == 13 || i == 15) 53 | cl_arg_types[i] = &ffi_type_slong; 54 | else 55 | cl_arg_types[i] = &ffi_type_double; 56 | } 57 | 58 | /* Initialize the cif */ 59 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, NARGS, 60 | &ffi_type_double, cl_arg_types) == FFI_OK); 61 | 62 | CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_double_fn, NULL, code) == FFI_OK); 63 | 64 | res = (((cls_ret_double)code))(0.1, 0.2, 0.3, 0.4, 5, 0.6, 0.7, 0.8, 0.9, 10, 65 | 1.1, 12, 1.3, 14, 1.5, 16); 66 | if (fabs(res - expected) < FLT_EPSILON) 67 | exit(0); 68 | else 69 | abort(); 70 | } 71 | -------------------------------------------------------------------------------- /src/ia64/ia64_flags.h: -------------------------------------------------------------------------------- 1 | /* ----------------------------------------------------------------------- 2 | ia64_flags.h - Copyright (c) 2000 Hewlett Packard Company 3 | 4 | IA64/unix Foreign Function Interface 5 | 6 | Original author: Hans Boehm, HP Labs 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining 9 | a copy of this software and associated documentation files (the 10 | ``Software''), to deal in the Software without restriction, including 11 | without limitation the rights to use, copy, modify, merge, publish, 12 | distribute, sublicense, and/or sell copies of the Software, and to 13 | permit persons to whom the Software is furnished to do so, subject to 14 | the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included 17 | in all copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 20 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | DEALINGS IN THE SOFTWARE. 27 | ----------------------------------------------------------------------- */ 28 | 29 | /* "Type" codes used between assembly and C. When used as a part of 30 | a cfi->flags value, the low byte will be these extra type codes, 31 | and bits 8-31 will be the actual size of the type. */ 32 | 33 | /* Small structures containing N words in integer registers. */ 34 | #define FFI_IA64_TYPE_SMALL_STRUCT (FFI_TYPE_LAST + 1) 35 | 36 | /* Homogeneous Floating Point Aggregates (HFAs) which are returned 37 | in FP registers. */ 38 | #define FFI_IA64_TYPE_HFA_FLOAT (FFI_TYPE_LAST + 2) 39 | #define FFI_IA64_TYPE_HFA_DOUBLE (FFI_TYPE_LAST + 3) 40 | #define FFI_IA64_TYPE_HFA_LDOUBLE (FFI_TYPE_LAST + 4) 41 | -------------------------------------------------------------------------------- /src/xtensa/ffitarget.h: -------------------------------------------------------------------------------- 1 | /* -----------------------------------------------------------------*-C-*- 2 | ffitarget.h - Copyright (c) 2013 Tensilica, Inc. 3 | Target configuration macros for XTENSA. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | ``Software''), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included 14 | in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | ----------------------------------------------------------------------- */ 25 | 26 | #ifndef LIBFFI_TARGET_H 27 | #define LIBFFI_TARGET_H 28 | 29 | #ifndef LIBFFI_H 30 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." 31 | #endif 32 | 33 | #ifndef LIBFFI_ASM 34 | typedef unsigned long ffi_arg; 35 | typedef signed long ffi_sarg; 36 | 37 | typedef enum ffi_abi { 38 | FFI_FIRST_ABI = 0, 39 | FFI_SYSV, 40 | FFI_LAST_ABI, 41 | FFI_DEFAULT_ABI = FFI_SYSV 42 | } ffi_abi; 43 | #endif 44 | 45 | #define FFI_REGISTER_NARGS 6 46 | 47 | /* ---- Definitions for closures ----------------------------------------- */ 48 | 49 | #define FFI_CLOSURES 1 50 | #define FFI_NATIVE_RAW_API 0 51 | #define FFI_TRAMPOLINE_SIZE 24 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /src/metag/ffitarget.h: -------------------------------------------------------------------------------- 1 | /* -----------------------------------------------------------------*-C-*- 2 | ffitarget.h - Copyright (c) 2013 Imagination Technologies Ltd. 3 | Target configuration macros for Meta 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | ``Software''), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included 14 | in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | 25 | ----------------------------------------------------------------------- */ 26 | 27 | #ifndef LIBFFI_TARGET_H 28 | #define LIBFFI_TARGET_H 29 | 30 | #ifndef LIBFFI_H 31 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." 32 | #endif 33 | 34 | #ifndef LIBFFI_ASM 35 | typedef unsigned long ffi_arg; 36 | typedef signed long ffi_sarg; 37 | 38 | typedef enum ffi_abi { 39 | FFI_FIRST_ABI = 0, 40 | FFI_SYSV, 41 | FFI_DEFAULT_ABI = FFI_SYSV, 42 | FFI_LAST_ABI = FFI_DEFAULT_ABI + 1, 43 | } ffi_abi; 44 | #endif 45 | 46 | /* ---- Definitions for closures ----------------------------------------- */ 47 | 48 | #define FFI_CLOSURES 1 49 | #define FFI_TRAMPOLINE_SIZE 48 50 | #define FFI_NATIVE_RAW_API 0 51 | 52 | #endif 53 | 54 | -------------------------------------------------------------------------------- /src/arc/ffitarget.h: -------------------------------------------------------------------------------- 1 | /* ----------------------------------------------------------------------- 2 | ffitarget.h - Copyright (c) 2012 Anthony Green 3 | Copyright (c) 2013 Synopsys, Inc. (www.synopsys.com) 4 | Target configuration macros for ARC. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files (the 8 | ``Software''), to deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included 15 | in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | IN NO EVENT SHALL RENESAS TECHNOLOGY BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | ----------------------------------------------------------------------- */ 26 | 27 | #ifndef LIBFFI_TARGET_H 28 | #define LIBFFI_TARGET_H 29 | 30 | #ifndef LIBFFI_H 31 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." 32 | #endif 33 | 34 | /* ---- Generic type definitions ----------------------------------------- */ 35 | 36 | #ifndef LIBFFI_ASM 37 | typedef unsigned long ffi_arg; 38 | typedef signed long ffi_sarg; 39 | 40 | typedef enum ffi_abi 41 | { 42 | FFI_FIRST_ABI = 0, 43 | FFI_ARCOMPACT, 44 | FFI_LAST_ABI, 45 | FFI_DEFAULT_ABI = FFI_ARCOMPACT 46 | } ffi_abi; 47 | #endif 48 | 49 | #define FFI_CLOSURES 1 50 | #define FFI_TRAMPOLINE_SIZE 12 51 | #define FFI_NATIVE_RAW_API 0 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /src/m32r/ffitarget.h: -------------------------------------------------------------------------------- 1 | /* -----------------------------------------------------------------*-C-*- 2 | ffitarget.h - Copyright (c) 2012 Anthony Green 3 | Copyright (c) 2004 Renesas Technology. 4 | Target configuration macros for M32R. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files (the 8 | ``Software''), to deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included 15 | in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | IN NO EVENT SHALL RENESAS TECHNOLOGY BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | ----------------------------------------------------------------------- */ 26 | 27 | #ifndef LIBFFI_TARGET_H 28 | #define LIBFFI_TARGET_H 29 | 30 | #ifndef LIBFFI_H 31 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." 32 | #endif 33 | 34 | /* ---- Generic type definitions ----------------------------------------- */ 35 | 36 | #ifndef LIBFFI_ASM 37 | typedef unsigned long ffi_arg; 38 | typedef signed long ffi_sarg; 39 | 40 | typedef enum ffi_abi 41 | { 42 | FFI_FIRST_ABI = 0, 43 | FFI_SYSV, 44 | FFI_LAST_ABI, 45 | FFI_DEFAULT_ABI = FFI_SYSV 46 | } ffi_abi; 47 | #endif 48 | 49 | #define FFI_CLOSURES 0 50 | #define FFI_TRAMPOLINE_SIZE 24 51 | #define FFI_NATIVE_RAW_API 0 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /src/moxie/ffitarget.h: -------------------------------------------------------------------------------- 1 | /* -----------------------------------------------------------------*-C-*- 2 | ffitarget.h - Copyright (c) 2012, 2013 Anthony Green 3 | Target configuration macros for Moxie 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | ``Software''), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included 14 | in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | 25 | ----------------------------------------------------------------------- */ 26 | 27 | #ifndef LIBFFI_TARGET_H 28 | #define LIBFFI_TARGET_H 29 | 30 | /* ---- System specific configurations ----------------------------------- */ 31 | 32 | #ifndef LIBFFI_ASM 33 | typedef unsigned long ffi_arg; 34 | typedef signed long ffi_sarg; 35 | 36 | typedef enum ffi_abi { 37 | FFI_FIRST_ABI = 0, 38 | FFI_EABI, 39 | FFI_DEFAULT_ABI = FFI_EABI, 40 | FFI_LAST_ABI = FFI_DEFAULT_ABI + 1 41 | } ffi_abi; 42 | #endif 43 | 44 | /* ---- Definitions for closures ----------------------------------------- */ 45 | 46 | #define FFI_CLOSURES 1 47 | #define FFI_NATIVE_RAW_API 0 48 | 49 | /* Trampolines are 12-bytes long. See ffi_prep_closure_loc. */ 50 | #define FFI_TRAMPOLINE_SIZE (12) 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /src/sh/ffitarget.h: -------------------------------------------------------------------------------- 1 | /* -----------------------------------------------------------------*-C-*- 2 | ffitarget.h - Copyright (c) 2012 Anthony Green 3 | Copyright (c) 1996-2003 Red Hat, Inc. 4 | Target configuration macros for SuperH. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files (the 8 | ``Software''), to deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included 15 | in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | 26 | ----------------------------------------------------------------------- */ 27 | 28 | #ifndef LIBFFI_TARGET_H 29 | #define LIBFFI_TARGET_H 30 | 31 | #ifndef LIBFFI_H 32 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." 33 | #endif 34 | 35 | /* ---- Generic type definitions ----------------------------------------- */ 36 | 37 | #ifndef LIBFFI_ASM 38 | typedef unsigned long ffi_arg; 39 | typedef signed long ffi_sarg; 40 | 41 | typedef enum ffi_abi { 42 | FFI_FIRST_ABI = 0, 43 | FFI_SYSV, 44 | FFI_LAST_ABI, 45 | FFI_DEFAULT_ABI = FFI_SYSV 46 | } ffi_abi; 47 | #endif 48 | 49 | #define FFI_CLOSURES 1 50 | #define FFI_TRAMPOLINE_SIZE 16 51 | #define FFI_NATIVE_RAW_API 0 52 | 53 | #endif 54 | 55 | -------------------------------------------------------------------------------- /include/ffi_cfi.h: -------------------------------------------------------------------------------- 1 | /* ----------------------------------------------------------------------- 2 | ffi_cfi.h - Copyright (c) 2014 Red Hat, Inc. 3 | 4 | Conditionally assemble cfi directives. Only necessary for building libffi. 5 | ----------------------------------------------------------------------- */ 6 | 7 | #ifndef FFI_CFI_H 8 | #define FFI_CFI_H 9 | 10 | #ifdef HAVE_AS_CFI_PSEUDO_OP 11 | 12 | # define cfi_startproc .cfi_startproc 13 | # define cfi_endproc .cfi_endproc 14 | # define cfi_def_cfa(reg, off) .cfi_def_cfa reg, off 15 | # define cfi_def_cfa_register(reg) .cfi_def_cfa_register reg 16 | # define cfi_def_cfa_offset(off) .cfi_def_cfa_offset off 17 | # define cfi_adjust_cfa_offset(off) .cfi_adjust_cfa_offset off 18 | # define cfi_offset(reg, off) .cfi_offset reg, off 19 | # define cfi_rel_offset(reg, off) .cfi_rel_offset reg, off 20 | # define cfi_register(r1, r2) .cfi_register r1, r2 21 | # define cfi_return_column(reg) .cfi_return_column reg 22 | # define cfi_restore(reg) .cfi_restore reg 23 | # define cfi_same_value(reg) .cfi_same_value reg 24 | # define cfi_undefined(reg) .cfi_undefined reg 25 | # define cfi_remember_state .cfi_remember_state 26 | # define cfi_restore_state .cfi_restore_state 27 | # define cfi_window_save .cfi_window_save 28 | # define cfi_personality(enc, exp) .cfi_personality enc, exp 29 | # define cfi_lsda(enc, exp) .cfi_lsda enc, exp 30 | # define cfi_escape(...) .cfi_escape __VA_ARGS__ 31 | 32 | #else 33 | 34 | # define cfi_startproc 35 | # define cfi_endproc 36 | # define cfi_def_cfa(reg, off) 37 | # define cfi_def_cfa_register(reg) 38 | # define cfi_def_cfa_offset(off) 39 | # define cfi_adjust_cfa_offset(off) 40 | # define cfi_offset(reg, off) 41 | # define cfi_rel_offset(reg, off) 42 | # define cfi_register(r1, r2) 43 | # define cfi_return_column(reg) 44 | # define cfi_restore(reg) 45 | # define cfi_same_value(reg) 46 | # define cfi_undefined(reg) 47 | # define cfi_remember_state 48 | # define cfi_restore_state 49 | # define cfi_window_save 50 | # define cfi_personality(enc, exp) 51 | # define cfi_lsda(enc, exp) 52 | # define cfi_escape(...) 53 | 54 | #endif /* HAVE_AS_CFI_PSEUDO_OP */ 55 | #endif /* FFI_CFI_H */ 56 | -------------------------------------------------------------------------------- /src/m68k/ffitarget.h: -------------------------------------------------------------------------------- 1 | /* -----------------------------------------------------------------*-C-*- 2 | ffitarget.h - Copyright (c) 2012 Anthony Green 3 | Copyright (c) 1996-2003 Red Hat, Inc. 4 | Target configuration macros for Motorola 68K. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files (the 8 | ``Software''), to deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included 15 | in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | 26 | ----------------------------------------------------------------------- */ 27 | 28 | #ifndef LIBFFI_TARGET_H 29 | #define LIBFFI_TARGET_H 30 | 31 | #ifndef LIBFFI_H 32 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." 33 | #endif 34 | 35 | #ifndef LIBFFI_ASM 36 | typedef unsigned long ffi_arg; 37 | typedef signed long ffi_sarg; 38 | 39 | typedef enum ffi_abi { 40 | FFI_FIRST_ABI = 0, 41 | FFI_SYSV, 42 | FFI_LAST_ABI, 43 | FFI_DEFAULT_ABI = FFI_SYSV 44 | } ffi_abi; 45 | #endif 46 | 47 | /* ---- Definitions for closures ----------------------------------------- */ 48 | 49 | #define FFI_CLOSURES 1 50 | #define FFI_TRAMPOLINE_SIZE 16 51 | #define FFI_NATIVE_RAW_API 0 52 | 53 | #endif 54 | 55 | -------------------------------------------------------------------------------- /testsuite/libffi.call/struct8.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call 2 | Purpose: Check structures. 3 | Limitations: none. 4 | PR: none. 5 | Originator: From the original ffitest.c */ 6 | 7 | /* { dg-do run } */ 8 | #include "ffitest.h" 9 | typedef struct 10 | { 11 | float f1; 12 | float f2; 13 | float f3; 14 | float f4; 15 | } test_structure_8; 16 | 17 | static test_structure_8 ABI_ATTR struct8 (test_structure_8 ts) 18 | { 19 | ts.f1 += 1; 20 | ts.f2 += 1; 21 | ts.f3 += 1; 22 | ts.f4 += 1; 23 | 24 | return ts; 25 | } 26 | 27 | int main (void) 28 | { 29 | ffi_cif cif; 30 | ffi_type *args[MAX_ARGS]; 31 | void *values[MAX_ARGS]; 32 | ffi_type ts8_type; 33 | ffi_type *ts8_type_elements[5]; 34 | 35 | test_structure_8 ts8_arg; 36 | 37 | /* This is a hack to get a properly aligned result buffer */ 38 | test_structure_8 *ts8_result = 39 | (test_structure_8 *) malloc (sizeof(test_structure_8)); 40 | 41 | ts8_type.size = 0; 42 | ts8_type.alignment = 0; 43 | ts8_type.type = FFI_TYPE_STRUCT; 44 | ts8_type.elements = ts8_type_elements; 45 | ts8_type_elements[0] = &ffi_type_float; 46 | ts8_type_elements[1] = &ffi_type_float; 47 | ts8_type_elements[2] = &ffi_type_float; 48 | ts8_type_elements[3] = &ffi_type_float; 49 | ts8_type_elements[4] = NULL; 50 | 51 | args[0] = &ts8_type; 52 | values[0] = &ts8_arg; 53 | 54 | /* Initialize the cif */ 55 | CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ts8_type, args) == FFI_OK); 56 | 57 | ts8_arg.f1 = 5.55f; 58 | ts8_arg.f2 = 55.5f; 59 | ts8_arg.f3 = -5.55f; 60 | ts8_arg.f4 = -55.5f; 61 | 62 | printf ("%g\n", ts8_arg.f1); 63 | printf ("%g\n", ts8_arg.f2); 64 | printf ("%g\n", ts8_arg.f3); 65 | printf ("%g\n", ts8_arg.f4); 66 | 67 | ffi_call(&cif, FFI_FN(struct8), ts8_result, values); 68 | 69 | printf ("%g\n", ts8_result->f1); 70 | printf ("%g\n", ts8_result->f2); 71 | printf ("%g\n", ts8_result->f3); 72 | printf ("%g\n", ts8_result->f4); 73 | 74 | CHECK(ts8_result->f1 == 5.55f + 1); 75 | CHECK(ts8_result->f2 == 55.5f + 1); 76 | CHECK(ts8_result->f3 == -5.55f + 1); 77 | CHECK(ts8_result->f4 == -55.5f + 1); 78 | 79 | free (ts8_result); 80 | exit(0); 81 | } 82 | -------------------------------------------------------------------------------- /src/avr32/ffitarget.h: -------------------------------------------------------------------------------- 1 | /* -----------------------------------------------------------------*-C-*- 2 | ffitarget.h - Copyright (c) 2012 Anthony Green 3 | Copyright (c) 2009 Bradley Smith 4 | Target configuration macros for AVR32. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files (the 8 | ``Software''), to deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included 15 | in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | 26 | ----------------------------------------------------------------------- */ 27 | 28 | #ifndef LIBFFI_TARGET_H 29 | #define LIBFFI_TARGET_H 30 | 31 | #ifndef LIBFFI_H 32 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." 33 | #endif 34 | 35 | #ifndef LIBFFI_ASM 36 | typedef unsigned long ffi_arg; 37 | typedef signed long ffi_sarg; 38 | 39 | typedef enum ffi_abi { 40 | FFI_FIRST_ABI = 0, 41 | FFI_SYSV, 42 | FFI_LAST_ABI, 43 | FFI_DEFAULT_ABI = FFI_SYSV 44 | } ffi_abi; 45 | #endif 46 | 47 | #define FFI_EXTRA_CIF_FIELDS unsigned int rstruct_flag 48 | 49 | /* Definitions for closures */ 50 | 51 | #define FFI_CLOSURES 1 52 | #define FFI_TRAMPOLINE_SIZE 36 53 | #define FFI_NATIVE_RAW_API 0 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /testsuite/libffi.closures/cls_pointer.c: -------------------------------------------------------------------------------- 1 | /* Area: ffi_call, closure_call 2 | Purpose: Check pointer arguments. 3 | Limitations: none. 4 | PR: none. 5 | Originator: Blake Chaffin 6/6/2007 */ 6 | 7 | /* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */ 8 | #include "ffitest.h" 9 | 10 | void* cls_pointer_fn(void* a1, void* a2) 11 | { 12 | void* result = (void*)((intptr_t)a1 + (intptr_t)a2); 13 | 14 | printf("0x%08x 0x%08x: 0x%08x\n", 15 | (unsigned int)(uintptr_t) a1, 16 | (unsigned int)(uintptr_t) a2, 17 | (unsigned int)(uintptr_t) result); 18 | 19 | return result; 20 | } 21 | 22 | static void 23 | cls_pointer_gn(ffi_cif* cif __UNUSED__, void* resp, 24 | void** args, void* userdata __UNUSED__) 25 | { 26 | void* a1 = *(void**)(args[0]); 27 | void* a2 = *(void**)(args[1]); 28 | 29 | *(void**)resp = cls_pointer_fn(a1, a2); 30 | } 31 | 32 | int main (void) 33 | { 34 | ffi_cif cif; 35 | void *code; 36 | ffi_closure* pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); 37 | void* args[3]; 38 | /* ffi_type cls_pointer_type; */ 39 | ffi_type* arg_types[3]; 40 | 41 | /* cls_pointer_type.size = sizeof(void*); 42 | cls_pointer_type.alignment = 0; 43 | cls_pointer_type.type = FFI_TYPE_POINTER; 44 | cls_pointer_type.elements = NULL;*/ 45 | 46 | void* arg1 = (void*)0x12345678; 47 | void* arg2 = (void*)0x89abcdef; 48 | ffi_arg res = 0; 49 | 50 | arg_types[0] = &ffi_type_pointer; 51 | arg_types[1] = &ffi_type_pointer; 52 | arg_types[2] = NULL; 53 | 54 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ffi_type_pointer, 55 | arg_types) == FFI_OK); 56 | 57 | args[0] = &arg1; 58 | args[1] = &arg2; 59 | args[2] = NULL; 60 | 61 | ffi_call(&cif, FFI_FN(cls_pointer_fn), &res, args); 62 | /* { dg-output "0x12345678 0x89abcdef: 0x9be02467" } */ 63 | printf("res: 0x%08x\n", (unsigned int) res); 64 | /* { dg-output "\nres: 0x9be02467" } */ 65 | 66 | CHECK(ffi_prep_closure_loc(pcl, &cif, cls_pointer_gn, NULL, code) == FFI_OK); 67 | 68 | res = (ffi_arg)(uintptr_t)((void*(*)(void*, void*))(code))(arg1, arg2); 69 | /* { dg-output "\n0x12345678 0x89abcdef: 0x9be02467" } */ 70 | printf("res: 0x%08x\n", (unsigned int) res); 71 | /* { dg-output "\nres: 0x9be02467" } */ 72 | 73 | exit(0); 74 | } 75 | -------------------------------------------------------------------------------- /testsuite/libffi.closures/closure.exp: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2003, 2006, 2009, 2010, 2014, 2019 Free Software Foundation, Inc. 2 | # Copyright (C) 2019 Anthony Green 3 | 4 | # This program is free software; you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation; either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; see the file COPYING3. If not see 16 | # . 17 | 18 | dg-init 19 | libffi-init 20 | 21 | global srcdir subdir 22 | 23 | if { [string match $compiler_vendor "microsoft"] } { 24 | # -wd4005 macro redefinition 25 | # -wd4244 implicit conversion to type of smaller size 26 | # -wd4305 truncation to smaller type 27 | # -wd4477 printf %lu of uintptr_t 28 | # -wd4312 implicit conversion to type of greater size 29 | # -wd4311 pointer truncation to unsigned long 30 | # -EHsc C++ Exception Handling (no SEH exceptions) 31 | set additional_options "-wd4005 -wd4244 -wd4305 -wd4477 -wd4312 -wd4311 -EHsc"; 32 | } else { 33 | set additional_options ""; 34 | } 35 | 36 | set tlist [lsort [glob -nocomplain -- $srcdir/$subdir/*.c]] 37 | 38 | if { [libffi_feature_test "#if FFI_CLOSURES"] } { 39 | run-many-tests $tlist "" 40 | } else { 41 | foreach test $tlist { 42 | unsupported "$test" 43 | } 44 | } 45 | 46 | set tlist [lsort [glob -nocomplain -- $srcdir/$subdir/*.cc]] 47 | 48 | # No C++ for or1k 49 | if { [istarget "or1k-*-*"] } { 50 | foreach test $tlist { 51 | unsupported "$test" 52 | } 53 | } else { 54 | if { [libffi_feature_test "#if FFI_CLOSURES"] } { 55 | run-many-tests $tlist $additional_options 56 | } else { 57 | foreach test $tlist { 58 | unsupported "$test" 59 | } 60 | } 61 | } 62 | 63 | dg-finish 64 | 65 | # Local Variables: 66 | # tcl-indent-level:4 67 | # End: 68 | -------------------------------------------------------------------------------- /src/alpha/ffitarget.h: -------------------------------------------------------------------------------- 1 | /* -----------------------------------------------------------------*-C-*- 2 | ffitarget.h - Copyright (c) 2012 Anthony Green 3 | Copyright (c) 1996-2003 Red Hat, Inc. 4 | Target configuration macros for Alpha. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files (the 8 | ``Software''), to deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included 15 | in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | 26 | ----------------------------------------------------------------------- */ 27 | 28 | #ifndef LIBFFI_TARGET_H 29 | #define LIBFFI_TARGET_H 30 | 31 | #ifndef LIBFFI_H 32 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." 33 | #endif 34 | 35 | #ifndef LIBFFI_ASM 36 | typedef unsigned long ffi_arg; 37 | typedef signed long ffi_sarg; 38 | 39 | typedef enum ffi_abi { 40 | FFI_FIRST_ABI = 0, 41 | FFI_OSF, 42 | FFI_LAST_ABI, 43 | FFI_DEFAULT_ABI = FFI_OSF 44 | } ffi_abi; 45 | #endif 46 | 47 | #define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION 48 | #define FFI_TARGET_HAS_COMPLEX_TYPE 49 | 50 | /* ---- Definitions for closures ----------------------------------------- */ 51 | 52 | #define FFI_CLOSURES 1 53 | #define FFI_GO_CLOSURES 1 54 | #define FFI_TRAMPOLINE_SIZE 24 55 | #define FFI_NATIVE_RAW_API 0 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /testsuite/libffi.complex/many_complex.inc: -------------------------------------------------------------------------------- 1 | /* -*-c-*- */ 2 | #include "ffitest.h" 3 | 4 | #include 5 | #include 6 | 7 | static _Complex T_C_TYPE many(_Complex T_C_TYPE c1, 8 | _Complex T_C_TYPE c2, 9 | _Complex T_C_TYPE c3, 10 | _Complex T_C_TYPE c4, 11 | _Complex T_C_TYPE c5, 12 | _Complex T_C_TYPE c6, 13 | _Complex T_C_TYPE c7, 14 | _Complex T_C_TYPE c8, 15 | _Complex T_C_TYPE c9, 16 | _Complex T_C_TYPE c10, 17 | _Complex T_C_TYPE c11, 18 | _Complex T_C_TYPE c12, 19 | _Complex T_C_TYPE c13) 20 | { 21 | printf("0 :%f,%fi\n" 22 | "1 :%f,%fi\n" 23 | "2 :%f,%fi\n" 24 | "3 :%f,%fi\n" 25 | "4 :%f,%fi\n" 26 | "5 :%f,%fi\n" 27 | "6 :%f,%fi\n" 28 | "7 :%f,%fi\n" 29 | "8 :%f,%fi\n" 30 | "9 :%f,%fi\n" 31 | "10:%f,%fi\n" 32 | "11:%f,%fi\n" 33 | "12:%f,%fi\n", 34 | T_CONV creal (c1), T_CONV cimag (c1), 35 | T_CONV creal (c2), T_CONV cimag (c2), 36 | T_CONV creal (c3), T_CONV cimag (c3), 37 | T_CONV creal (c4), T_CONV cimag (c4), 38 | T_CONV creal (c5), T_CONV cimag (c5), 39 | T_CONV creal (c6), T_CONV cimag (c6), 40 | T_CONV creal (c7), T_CONV cimag (c7), 41 | T_CONV creal (c8), T_CONV cimag (c8), 42 | T_CONV creal (c9), T_CONV cimag (c9), 43 | T_CONV creal (c10), T_CONV cimag (c10), 44 | T_CONV creal (c11), T_CONV cimag (c11), 45 | T_CONV creal (c12), T_CONV cimag (c12), 46 | T_CONV creal (c13), T_CONV cimag (c13)); 47 | 48 | return (c1+c2-c3-c4+c5+c6+c7-c8-c9-c10-c11+c12+c13); 49 | } 50 | 51 | int main (void) 52 | { 53 | ffi_cif cif; 54 | ffi_type *args[13]; 55 | void *values[13]; 56 | _Complex T_C_TYPE ca[13]; 57 | _Complex T_C_TYPE c, cc; 58 | int i; 59 | 60 | for (i = 0; i < 13; i++) 61 | { 62 | args[i] = &T_FFI_TYPE; 63 | values[i] = &ca[i]; 64 | ca[i] = i + (-20 - i) * I; 65 | } 66 | 67 | /* Initialize the cif */ 68 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 13, &T_FFI_TYPE, args) == FFI_OK); 69 | 70 | ffi_call(&cif, FFI_FN(many), &c, values); 71 | 72 | cc = many(ca[0], ca[1], ca[2], ca[3], ca[4], ca[5], ca[6], ca[7], ca[8], 73 | ca[9], ca[10], ca[11], ca[12]); 74 | CHECK(creal (cc) == creal (c)); 75 | CHECK(cimag (cc) == cimag (c)); 76 | 77 | exit(0); 78 | } 79 | -------------------------------------------------------------------------------- /src/or1k/ffitarget.h: -------------------------------------------------------------------------------- 1 | /* ----------------------------------------------------------------------- 2 | ffitarget.h - Copyright (c) 2014 Sebastian Macke 3 | 4 | OpenRISC Target configuration macros 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files (the 8 | ``Software''), to deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included 15 | in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | ----------------------------------------------------------------------- */ 26 | 27 | #ifndef LIBFFI_TARGET_H 28 | #define LIBFFI_TARGET_H 29 | 30 | #ifndef LIBFFI_H 31 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." 32 | #endif 33 | 34 | /* ---- System specific configurations ----------------------------------- */ 35 | 36 | #ifndef LIBFFI_ASM 37 | typedef unsigned long ffi_arg; 38 | typedef signed long ffi_sarg; 39 | 40 | typedef enum ffi_abi { 41 | FFI_FIRST_ABI = 0, 42 | FFI_SYSV, 43 | FFI_LAST_ABI, 44 | FFI_DEFAULT_ABI = FFI_SYSV 45 | } ffi_abi; 46 | #endif 47 | 48 | /* ---- Definitions for closures ----------------------------------------- */ 49 | 50 | #define FFI_CLOSURES 1 51 | #define FFI_NATIVE_RAW_API 0 52 | #define FFI_TRAMPOLINE_SIZE (24) 53 | 54 | #define FFI_TARGET_SPECIFIC_VARIADIC 1 55 | #define FFI_EXTRA_CIF_FIELDS unsigned nfixedargs; 56 | 57 | #endif 58 | 59 | -------------------------------------------------------------------------------- /src/sh64/ffitarget.h: -------------------------------------------------------------------------------- 1 | /* -----------------------------------------------------------------*-C-*- 2 | ffitarget.h - Copyright (c) 2012 Anthony Green 3 | Copyright (c) 1996-2003 Red Hat, Inc. 4 | Target configuration macros for SuperH - SHmedia. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files (the 8 | ``Software''), to deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included 15 | in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | 26 | ----------------------------------------------------------------------- */ 27 | 28 | #ifndef LIBFFI_TARGET_H 29 | #define LIBFFI_TARGET_H 30 | 31 | #ifndef LIBFFI_H 32 | #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." 33 | #endif 34 | 35 | /* ---- Generic type definitions ----------------------------------------- */ 36 | 37 | #ifndef LIBFFI_ASM 38 | typedef unsigned long ffi_arg; 39 | typedef signed long ffi_sarg; 40 | 41 | typedef enum ffi_abi { 42 | FFI_FIRST_ABI = 0, 43 | FFI_SYSV, 44 | FFI_LAST_ABI, 45 | FFI_DEFAULT_ABI = FFI_SYSV 46 | } ffi_abi; 47 | 48 | #define FFI_EXTRA_CIF_FIELDS long long flags2 49 | #endif 50 | 51 | /* ---- Definitions for closures ----------------------------------------- */ 52 | 53 | #define FFI_CLOSURES 1 54 | #define FFI_TRAMPOLINE_SIZE 32 55 | #define FFI_NATIVE_RAW_API 0 56 | 57 | #endif 58 | 59 | -------------------------------------------------------------------------------- /m4/ax_check_compile_flag.m4: -------------------------------------------------------------------------------- 1 | # =========================================================================== 2 | # https://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html 3 | # =========================================================================== 4 | # 5 | # SYNOPSIS 6 | # 7 | # AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT]) 8 | # 9 | # DESCRIPTION 10 | # 11 | # Check whether the given FLAG works with the current language's compiler 12 | # or gives an error. (Warnings, however, are ignored) 13 | # 14 | # ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on 15 | # success/failure. 16 | # 17 | # If EXTRA-FLAGS is defined, it is added to the current language's default 18 | # flags (e.g. CFLAGS) when the check is done. The check is thus made with 19 | # the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to 20 | # force the compiler to issue an error when a bad flag is given. 21 | # 22 | # INPUT gives an alternative input source to AC_COMPILE_IFELSE. 23 | # 24 | # NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this 25 | # macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG. 26 | # 27 | # LICENSE 28 | # 29 | # Copyright (c) 2008 Guido U. Draheim 30 | # Copyright (c) 2011 Maarten Bosmans 31 | # 32 | # Copying and distribution of this file, with or without modification, are 33 | # permitted in any medium without royalty provided the copyright notice 34 | # and this notice are preserved. This file is offered as-is, without any 35 | # warranty. 36 | 37 | #serial 6 38 | 39 | AC_DEFUN([AX_CHECK_COMPILE_FLAG], 40 | [AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF 41 | AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl 42 | AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [ 43 | ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS 44 | _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1" 45 | AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])], 46 | [AS_VAR_SET(CACHEVAR,[yes])], 47 | [AS_VAR_SET(CACHEVAR,[no])]) 48 | _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags]) 49 | AS_VAR_IF(CACHEVAR,yes, 50 | [m4_default([$2], :)], 51 | [m4_default([$3], :)]) 52 | AS_VAR_POPDEF([CACHEVAR])dnl 53 | ])dnl AX_CHECK_COMPILE_FLAGS 54 | --------------------------------------------------------------------------------