From b4b575ce7854f4a49de8de93f38b7639e01b040b Mon Sep 17 00:00:00 2001 From: Anthony Green Date: Wed, 26 Dec 2012 16:28:02 +0000 Subject: libffi merge From-SVN: r194722 --- libffi/ChangeLog | 307 ++++++ libffi/ChangeLog.libffi | 584 +++++++++++ libffi/Makefile.am | 81 +- libffi/README | 114 ++- libffi/configure | 201 +++- libffi/configure.ac | 132 ++- libffi/generate-ios-source-and-headers.py | 160 +++ libffi/generate-osx-source-and-headers.py | 153 +++ libffi/libffi.xcodeproj/project.pbxproj | 579 +++++++++++ libffi/man/Makefile.am | 4 +- libffi/man/Makefile.in | 101 +- libffi/src/aarch64/ffi.c | 1076 ++++++++++++++++++++ libffi/src/aarch64/ffitarget.h | 59 ++ libffi/src/aarch64/sysv.S | 307 ++++++ libffi/src/arm/ffi.c | 4 + libffi/src/arm/sysv.S | 13 +- libffi/src/arm/trampoline.S | 2 +- libffi/src/bfin/ffi.c | 195 ++++ libffi/src/bfin/ffitarget.h | 43 + libffi/src/bfin/sysv.S | 177 ++++ libffi/src/closures.c | 27 + libffi/src/m68k/ffi.c | 83 +- libffi/src/m68k/sysv.S | 53 +- libffi/src/powerpc/ffi_darwin.c | 6 +- libffi/src/prep_cif.c | 13 + libffi/src/tile/ffi.c | 355 +++++++ libffi/src/tile/ffitarget.h | 65 ++ libffi/src/tile/tile.S | 360 +++++++ libffi/src/x86/ffi.c | 29 +- libffi/src/x86/ffi64.c | 8 +- libffi/src/x86/ffitarget.h | 7 +- libffi/src/x86/win32.S | 168 +-- libffi/testsuite/Makefile.am | 69 ++ libffi/testsuite/Makefile.in | 158 ++- libffi/testsuite/lib/libffi.exp | 16 +- libffi/testsuite/libffi.call/closure_stdcall.c | 8 + libffi/testsuite/libffi.call/closure_thiscall.c | 8 + libffi/testsuite/libffi.call/cls_12byte.c | 8 +- libffi/testsuite/libffi.call/cls_16byte.c | 8 +- libffi/testsuite/libffi.call/cls_18byte.c | 8 +- libffi/testsuite/libffi.call/cls_19byte.c | 8 +- libffi/testsuite/libffi.call/cls_1_1byte.c | 8 +- libffi/testsuite/libffi.call/cls_20byte.c | 8 +- libffi/testsuite/libffi.call/cls_20byte1.c | 8 +- libffi/testsuite/libffi.call/cls_24byte.c | 10 +- libffi/testsuite/libffi.call/cls_2byte.c | 8 +- libffi/testsuite/libffi.call/cls_3_1byte.c | 8 +- libffi/testsuite/libffi.call/cls_3byte1.c | 8 +- libffi/testsuite/libffi.call/cls_3byte2.c | 8 +- libffi/testsuite/libffi.call/cls_4_1byte.c | 8 +- libffi/testsuite/libffi.call/cls_4byte.c | 8 +- libffi/testsuite/libffi.call/cls_5_1_byte.c | 8 +- libffi/testsuite/libffi.call/cls_5byte.c | 8 +- libffi/testsuite/libffi.call/cls_64byte.c | 10 +- libffi/testsuite/libffi.call/cls_6_1_byte.c | 8 +- libffi/testsuite/libffi.call/cls_6byte.c | 8 +- libffi/testsuite/libffi.call/cls_7_1_byte.c | 8 +- libffi/testsuite/libffi.call/cls_7byte.c | 8 +- libffi/testsuite/libffi.call/cls_8byte.c | 8 +- libffi/testsuite/libffi.call/cls_9byte1.c | 8 +- libffi/testsuite/libffi.call/cls_9byte2.c | 8 +- libffi/testsuite/libffi.call/cls_align_double.c | 8 +- libffi/testsuite/libffi.call/cls_align_float.c | 8 +- .../testsuite/libffi.call/cls_align_longdouble.c | 8 +- .../libffi.call/cls_align_longdouble_split.c | 8 +- .../libffi.call/cls_align_longdouble_split2.c | 8 +- libffi/testsuite/libffi.call/cls_align_pointer.c | 8 +- libffi/testsuite/libffi.call/cls_align_sint16.c | 8 +- libffi/testsuite/libffi.call/cls_align_sint32.c | 8 +- libffi/testsuite/libffi.call/cls_align_sint64.c | 8 +- libffi/testsuite/libffi.call/cls_align_uint16.c | 8 +- libffi/testsuite/libffi.call/cls_align_uint32.c | 8 +- libffi/testsuite/libffi.call/cls_align_uint64.c | 8 +- libffi/testsuite/libffi.call/cls_dbls_struct.c | 4 +- libffi/testsuite/libffi.call/cls_double_va.c | 1 - libffi/testsuite/libffi.call/cls_longdouble_va.c | 1 - libffi/testsuite/libffi.call/cls_pointer_stack.c | 6 +- libffi/testsuite/libffi.call/cls_struct_va1.c | 114 +++ libffi/testsuite/libffi.call/cls_uchar_va.c | 44 + libffi/testsuite/libffi.call/cls_uint_va.c | 45 + libffi/testsuite/libffi.call/cls_ulong_va.c | 45 + libffi/testsuite/libffi.call/cls_ushort_va.c | 44 + libffi/testsuite/libffi.call/err_bad_typedef.c | 4 +- libffi/testsuite/libffi.call/fastthis1_win32.c | 2 +- libffi/testsuite/libffi.call/fastthis2_win32.c | 2 +- libffi/testsuite/libffi.call/fastthis3_win32.c | 2 +- libffi/testsuite/libffi.call/ffitest.h | 17 + libffi/testsuite/libffi.call/float_va.c | 14 +- libffi/testsuite/libffi.call/huge_struct.c | 26 +- libffi/testsuite/libffi.call/nested_struct.c | 12 +- libffi/testsuite/libffi.call/nested_struct1.c | 14 +- libffi/testsuite/libffi.call/nested_struct10.c | 12 +- libffi/testsuite/libffi.call/nested_struct11.c | 121 +++ libffi/testsuite/libffi.call/nested_struct2.c | 10 +- libffi/testsuite/libffi.call/nested_struct3.c | 10 +- libffi/testsuite/libffi.call/nested_struct4.c | 10 +- libffi/testsuite/libffi.call/nested_struct5.c | 10 +- libffi/testsuite/libffi.call/nested_struct6.c | 12 +- libffi/testsuite/libffi.call/nested_struct7.c | 10 +- libffi/testsuite/libffi.call/nested_struct8.c | 12 +- libffi/testsuite/libffi.call/nested_struct9.c | 12 +- libffi/testsuite/libffi.call/stret_large.c | 10 +- libffi/testsuite/libffi.call/stret_large2.c | 10 +- libffi/testsuite/libffi.call/stret_medium.c | 10 +- libffi/testsuite/libffi.call/stret_medium2.c | 10 +- libffi/testsuite/libffi.call/strlen2_win32.c | 3 +- libffi/testsuite/libffi.call/struct1.c | 12 +- libffi/testsuite/libffi.call/struct1_win32.c | 14 +- libffi/testsuite/libffi.call/struct2.c | 10 +- libffi/testsuite/libffi.call/struct2_win32.c | 12 +- libffi/testsuite/libffi.call/struct3.c | 9 +- libffi/testsuite/libffi.call/struct4.c | 13 +- libffi/testsuite/libffi.call/struct5.c | 13 +- libffi/testsuite/libffi.call/struct6.c | 14 +- libffi/testsuite/libffi.call/struct7.c | 14 +- libffi/testsuite/libffi.call/struct8.c | 13 +- libffi/testsuite/libffi.call/struct9.c | 13 +- libffi/testsuite/libffi.call/testclosure.c | 4 +- libffi/testsuite/libffi.call/uninitialized.c | 61 ++ libffi/testsuite/libffi.call/va_1.c | 196 ++++ libffi/testsuite/libffi.call/va_struct1.c | 121 +++ libffi/testsuite/libffi.call/va_struct2.c | 123 +++ libffi/testsuite/libffi.call/va_struct3.c | 125 +++ 123 files changed, 6789 insertions(+), 654 deletions(-) create mode 100644 libffi/ChangeLog.libffi create mode 100644 libffi/generate-ios-source-and-headers.py create mode 100644 libffi/generate-osx-source-and-headers.py create mode 100644 libffi/libffi.xcodeproj/project.pbxproj create mode 100644 libffi/src/aarch64/ffi.c create mode 100644 libffi/src/aarch64/ffitarget.h create mode 100644 libffi/src/aarch64/sysv.S create mode 100644 libffi/src/bfin/ffi.c create mode 100644 libffi/src/bfin/ffitarget.h create mode 100644 libffi/src/bfin/sysv.S create mode 100644 libffi/src/tile/ffi.c create mode 100644 libffi/src/tile/ffitarget.h create mode 100644 libffi/src/tile/tile.S create mode 100644 libffi/testsuite/libffi.call/cls_struct_va1.c create mode 100644 libffi/testsuite/libffi.call/cls_uchar_va.c create mode 100644 libffi/testsuite/libffi.call/cls_uint_va.c create mode 100644 libffi/testsuite/libffi.call/cls_ulong_va.c create mode 100644 libffi/testsuite/libffi.call/cls_ushort_va.c create mode 100644 libffi/testsuite/libffi.call/nested_struct11.c create mode 100644 libffi/testsuite/libffi.call/uninitialized.c create mode 100644 libffi/testsuite/libffi.call/va_1.c create mode 100644 libffi/testsuite/libffi.call/va_struct1.c create mode 100644 libffi/testsuite/libffi.call/va_struct2.c create mode 100644 libffi/testsuite/libffi.call/va_struct3.c (limited to 'libffi') diff --git a/libffi/ChangeLog b/libffi/ChangeLog index 56d7725..62332c6 100644 --- a/libffi/ChangeLog +++ b/libffi/ChangeLog @@ -3,6 +3,63 @@ * src/powerpc/linux64_closure.S: Add new ABI support. * src/powerpc/linux64.S: Likewise. +2012-10-30 Magnus Granberg + Pavel Labushev + + * configure.ac: New options pax_emutramp + * configure, fficonfig.h.in: Regenerated + * src/closures.c: New function emutramp_enabled_check() and + checks. + +2012-10-30 Frederick Cheung + + * configure.ac: Enable FFI_MAP_EXEC_WRIT for Darwin 12 (mountain + lion) and future version. + * configure: Rebuild. + +2012-10-30 James Greenhalgh + Marcus Shawcroft + + * README: Add details of aarch64 port. + * src/aarch64/ffi.c: New. + * src/aarch64/ffitarget.h: Likewise. + * src/aarch64/sysv.S: Likewise. + * Makefile.am: Support aarch64. + * configure.ac: Support aarch64. + * Makefile.in, configure: Rebuilt. + +2012-10-30 James Greenhalgh + Marcus Shawcroft + + * testsuite/lib/libffi.exp: Add support for aarch64. + * testsuite/libffi.call/cls_struct_va1.c: New. + * testsuite/libffi.call/cls_uchar_va.c: Likewise. + * testsuite/libffi.call/cls_uint_va.c: Likewise. + * testsuite/libffi.call/cls_ulong_va.c: Likewise. + * testsuite/libffi.call/cls_ushort_va.c: Likewise. + * testsuite/libffi.call/nested_struct11.c: Likewise. + * testsuite/libffi.call/uninitialized.c: Likewise. + * testsuite/libffi.call/va_1.c: Likewise. + * testsuite/libffi.call/va_struct1.c: Likewise. + * testsuite/libffi.call/va_struct2.c: Likewise. + * testsuite/libffi.call/va_struct3.c: Likewise. + +2012-10-12 Walter Lee + + * Makefile.am: Add TILE-Gx/TILEPro support. + * configure.ac: Likewise. + * Makefile.in: Regenerate. + * configure: Likewise. + * src/prep_cif.c (ffi_prep_cif_core): Handle TILE-Gx/TILEPro. + * src/tile: New directory. + * src/tile/ffi.c: New file. + * src/tile/ffitarget.h: Ditto. + * src/tile/tile.S: Ditto. + +2012-10-12 Matthias Klose + + * generate-osx-source-and-headers.py: Normalize whitespace. + 2012-09-14 David Edelsohn * configure: Regenerated. @@ -29,6 +86,248 @@ * configure: Regenerated. +2012-05-05 Nicolas Lelong + + * libffi.xcodeproj/project.pbxproj: Fixes. + * README: Update for iOS builds. + +2012-04-23 Alexandre Keunecke I. de Mendonca + + * configure.ac: Add Blackfin/sysv support + * Makefile.am: Add Blackfin/sysv support + * src/bfin/ffi.c: Add Blackfin/sysv support + * src/bfin/ffitarget.h: Add Blackfin/sysv support + +2012-04-11 Anthony Green + + * Makefile.am (EXTRA_DIST): Add new script. + * Makefile.in: Rebuilt. + +2012-04-11 Zachary Waldowski + + * generate-ios-source-and-headers.py, + libffi.xcodeproj/project.pbxproj: Support a Mac static library via + Xcode. Set iOS compatibility to 4.0. Move iOS trampoline + generation into an Xcode "run script" phase. Include both as + Xcode build scripts. Don't always regenerate config files. + +2012-04-10 Anthony Green + + * src/powerpc/ffi_darwin.c (ffi_prep_args): Add missing semicolon. + +2012-04-06 Anthony Green + + * Makefile.am (EXTRA_DIST): Add new iOS/xcode files. + * Makefile.in: Rebuilt. + +2012-04-06 Mike Lewis + + * generate-ios-source-and-headers.py: New file. + * libffi.xcodeproj/project.pbxproj: New file. + * README: Update instructions on building iOS binary. + * build-ios.sh: Delete. + +2012-04-06 Anthony Green + + * src/x86/ffi64.c (UINT128): Define differently for Intel and GNU + compilers, then use it. + +2012-04-06 H.J. Lu + + * m4/libtool.m4 (_LT_ENABLE_LOCK): Support x32. + +2012-04-06 Anthony Green + + * testsuite/Makefile.am (EXTRA_DIST): Add missing test cases. + * testsuite/Makefile.in: Rebuilt. + +2012-04-05 Zachary Waldowski + + * include/ffi.h.in: Add missing trampoline table fields. + * src/arm/sysv.S: Fix ENTRY definition, and wrap symbol references + in CNAME. + * src/x86/ffi.c: Wrap Windows specific code in ifdefs. + +2012-03-29 Peter Rosin + + * src/x86/win32.S (ffi_closure_raw_THISCALL): Unify the frame + generation, fix the ENDP label and remove the surplus third arg + from the 'lea' insn. + +2012-03-29 Peter Rosin + + * src/x86/win32.S (ffi_closure_raw_SYSV): Make the 'stubraw' label + visible outside the PROC, so that ffi_closure_raw_THISCALL can see + it. Also instruct the assembler to add a frame to the function. + +2012-03-23 Peter Rosin + + * Makefile.am (AM_CPPFLAGS): Add -DFFI_BUILDING. + * Makefile.in: Rebuilt. + * include/ffi.h.in [MSVC]: Add __declspec(dllimport) decorations + to all data exports, when compiling libffi clients using MSVC. + +2012-03-29 Peter Rosin + + * src/x86/ffitarget.h (ffi_abi): Add new ABI FFI_MS_CDECL and + make it the default for MSVC. + (FFI_TYPE_MS_STRUCT): New structure return convention. + * src/x86/ffi.c (ffi_prep_cif_machdep): Tweak the structure + return convention for FFI_MS_CDECL to be FFI_TYPE_MS_STRUCT + instead of an ordinary FFI_TYPE_STRUCT. + (ffi_prep_args): Treat FFI_TYPE_MS_STRUCT as FFI_TYPE_STRUCT. + (ffi_call): Likewise. + (ffi_prep_incoming_args_SYSV): Likewise. + (ffi_raw_call): Likewise. + (ffi_prep_closure_loc): Treat FFI_MS_CDECL as FFI_SYSV. + * src/x86/win32.S (ffi_closure_SYSV): For FFI_TYPE_MS_STRUCT, + return a pointer to the result structure in eax and don't pop + that pointer from the stack, the caller takes care of it. + (ffi_call_win32): Treat FFI_TYPE_MS_STRUCT as FFI_TYPE_STRUCT. + (ffi_closure_raw_SYSV): Likewise. + +2012-03-22 Peter Rosin + + * testsuite/libffi.call/closure_stdcall.c [MSVC]: Add inline + assembly version with Intel syntax. + * testsuite/libffi.call/closure_thiscall.c [MSVC]: Likewise. + +2012-03-23 Peter Rosin + + * testsuite/libffi.call/ffitest.h: Provide abstration of + __attribute__((fastcall)) in the form of a __FASTCALL__ + define. Define it to __fastcall for MSVC. + * testsuite/libffi.call/fastthis1_win32.c: Use the above. + * testsuite/libffi.call/fastthis2_win32.c: Likewise. + * testsuite/libffi.call/fastthis3_win32.c: Likewise. + * testsuite/libffi.call/strlen2_win32.c: Likewise. + * testsuite/libffi.call/struct1_win32.c: Likewise. + * testsuite/libffi.call/struct2_win32.c: Likewise. + +2012-03-22 Peter Rosin + + * src/x86/win32.S [MSVC] (ffi_closure_THISCALL): Remove the manual + frame on function entry, MASM adds one automatically. + +2012-03-22 Peter Rosin + + * testsuite/libffi.call/ffitest.h [MSVC]: Add kludge for missing + bits in the MSVC headers. + +2012-03-22 Peter Rosin + + * testsuite/libffi.call/cls_12byte.c: Adjust to the C89 style + with no declarations after statements. + * testsuite/libffi.call/cls_16byte.c: Likewise. + * testsuite/libffi.call/cls_18byte.c: Likewise. + * testsuite/libffi.call/cls_19byte.c: Likewise. + * testsuite/libffi.call/cls_1_1byte.c: Likewise. + * testsuite/libffi.call/cls_20byte.c: Likewise. + * testsuite/libffi.call/cls_20byte1.c: Likewise. + * testsuite/libffi.call/cls_24byte.c: Likewise. + * testsuite/libffi.call/cls_2byte.c: Likewise. + * testsuite/libffi.call/cls_3_1byte.c: Likewise. + * testsuite/libffi.call/cls_3byte1.c: Likewise. + * testsuite/libffi.call/cls_3byte2.c: Likewise. + * testsuite/libffi.call/cls_4_1byte.c: Likewise. + * testsuite/libffi.call/cls_4byte.c: Likewise. + * testsuite/libffi.call/cls_5_1_byte.c: Likewise. + * testsuite/libffi.call/cls_5byte.c: Likewise. + * testsuite/libffi.call/cls_64byte.c: Likewise. + * testsuite/libffi.call/cls_6_1_byte.c: Likewise. + * testsuite/libffi.call/cls_6byte.c: Likewise. + * testsuite/libffi.call/cls_7_1_byte.c: Likewise. + * testsuite/libffi.call/cls_7byte.c: Likewise. + * testsuite/libffi.call/cls_8byte.c: Likewise. + * testsuite/libffi.call/cls_9byte1.c: Likewise. + * testsuite/libffi.call/cls_9byte2.c: Likewise. + * testsuite/libffi.call/cls_align_double.c: Likewise. + * testsuite/libffi.call/cls_align_float.c: Likewise. + * testsuite/libffi.call/cls_align_longdouble.c: Likewise. + * testsuite/libffi.call/cls_align_longdouble_split.c: Likewise. + * testsuite/libffi.call/cls_align_longdouble_split2.c: Likewise. + * testsuite/libffi.call/cls_align_pointer.c: Likewise. + * testsuite/libffi.call/cls_align_sint16.c: Likewise. + * testsuite/libffi.call/cls_align_sint32.c: Likewise. + * testsuite/libffi.call/cls_align_sint64.c: Likewise. + * testsuite/libffi.call/cls_align_uint16.c: Likewise. + * testsuite/libffi.call/cls_align_uint32.c: Likewise. + * testsuite/libffi.call/cls_align_uint64.c: Likewise. + * testsuite/libffi.call/cls_dbls_struct.c: Likewise. + * testsuite/libffi.call/cls_pointer_stack.c: Likewise. + * testsuite/libffi.call/err_bad_typedef.c: Likewise. + * testsuite/libffi.call/huge_struct.c: Likewise. + * testsuite/libffi.call/nested_struct.c: Likewise. + * testsuite/libffi.call/nested_struct1.c: Likewise. + * testsuite/libffi.call/nested_struct10.c: Likewise. + * testsuite/libffi.call/nested_struct2.c: Likewise. + * testsuite/libffi.call/nested_struct3.c: Likewise. + * testsuite/libffi.call/nested_struct4.c: Likewise. + * testsuite/libffi.call/nested_struct5.c: Likewise. + * testsuite/libffi.call/nested_struct6.c: Likewise. + * testsuite/libffi.call/nested_struct7.c: Likewise. + * testsuite/libffi.call/nested_struct8.c: Likewise. + * testsuite/libffi.call/nested_struct9.c: Likewise. + * testsuite/libffi.call/stret_large.c: Likewise. + * testsuite/libffi.call/stret_large2.c: Likewise. + * testsuite/libffi.call/stret_medium.c: Likewise. + * testsuite/libffi.call/stret_medium2.c: Likewise. + * testsuite/libffi.call/struct1.c: Likewise. + * testsuite/libffi.call/struct1_win32.c: Likewise. + * testsuite/libffi.call/struct2.c: Likewise. + * testsuite/libffi.call/struct2_win32.c: Likewise. + * testsuite/libffi.call/struct3.c: Likewise. + * testsuite/libffi.call/struct4.c: Likewise. + * testsuite/libffi.call/struct5.c: Likewise. + * testsuite/libffi.call/struct6.c: Likewise. + * testsuite/libffi.call/struct7.c: Likewise. + * testsuite/libffi.call/struct8.c: Likewise. + * testsuite/libffi.call/struct9.c: Likewise. + * testsuite/libffi.call/testclosure.c: Likewise. + +2012-03-21 Peter Rosin + + * testsuite/libffi.call/float_va.c (float_va_fn): Use %f when + printing doubles (%lf is for long doubles). + (main): Likewise. + +2012-03-21 Peter Rosin + + * testsuite/lib/target-libpath.exp [*-*-cygwin*, *-*-mingw*] + (set_ld_library_path_env_vars): Add the library search dir to PATH + (and save PATH for later). + (restore_ld_library_path_env_vars): Restore PATH. + +2012-03-20 Peter Rosin + + * testsuite/libffi.call/strlen2_win32.c (main): Remove bug. + * src/x86/win32.S [MSVC] (ffi_closure_SYSV): Make the 'stub' label + visible outside the PROC, so that ffi_closure_THISCALL can see it. + +2012-03-20 Peter Rosin + + * testsuite/libffi.call/strlen2_win32.c (main): Remove bug. + * src/x86/win32.S [MSVC] (ffi_closure_SYSV): Make the 'stub' label + visible outside the PROC, so that ffi_closure_THISCALL can see it. + +2012-03-19 Alan Hourihane + + * src/m68k/ffi.c: Add MINT support. + * src/m68k/sysv.S: Ditto. + +2012-03-19 chennam + + * src/powerpc/ffi_darwin.c (ffi_prep_closure_loc): Fix AIX closure + support. + +2012-03-06 Chung-Lin Tang + + * src/arm/ffi.c (ffi_call): Add __ARM_EABI__ guard around call to + ffi_call_VFP(). + (ffi_prep_closure_loc): Add __ARM_EABI__ guard around use of + ffi_closure_VFP. + * src/arm/sysv.S: Add __ARM_EABI__ guard around VFP code. + 2012-04-02 Peter Bergner * src/powerpc/ffi.c (ffi_prep_args_SYSV): Declare double_tmp. @@ -37,6 +336,14 @@ (ffi_call): Silence possibly undefined warning. (ffi_closure_helper_SYSV): Declare variable type. +2012-04-02 Peter Rosin + + * src/x86/win32.S (ffi_call_win32): Sign/zero extend the return + value in the Intel version as is already done for the AT&T version. + (ffi_closure_SYSV): Likewise. + (ffi_closure_raw_SYSV): Likewise. + (ffi_closure_STDCALL): Likewise. + 2012-03-13 Kaz Kojima * src/sh/ffi.c (ffi_prep_closure_loc): Don't ASSERT ABI test, diff --git a/libffi/ChangeLog.libffi b/libffi/ChangeLog.libffi new file mode 100644 index 0000000..f3ee8b0 --- /dev/null +++ b/libffi/ChangeLog.libffi @@ -0,0 +1,584 @@ +2011-02-08 Andreas Tobler + + * testsuite/lib/libffi.exp: Tweak for stand-alone mode. + +2009-12-25 Samuli Suominen + + * configure.ac: Undefine _AC_ARG_VAR_PRECIOUS for autoconf 2.64. + * configure: Rebuilt. + * fficonfig.h.in: Rebuilt. + +2009-06-16 Andrew Haley + + * testsuite/libffi.call/cls_align_sint64.c, + testsuite/libffi.call/cls_align_uint64.c, + testsuite/libffi.call/cls_longdouble_va.c, + testsuite/libffi.call/cls_ulonglong.c, + testsuite/libffi.call/return_ll1.c, + testsuite/libffi.call/stret_medium2.c: Fix printf format + specifiers. + * testsuite/libffi.call/huge_struct.c: Ad x86 XFAILs. + * testsuite/libffi.call/float2.c: Fix dg-excess-errors. + * testsuite/libffi.call/ffitest.h, + testsuite/libffi.special/ffitestcxx.h (PRIdLL, PRIuLL): Define. + +2009-06-12 Andrew Haley + + * testsuite/libffi.call/cls_align_sint64.c, + testsuite/libffi.call/cls_align_uint64.c, + testsuite/libffi.call/cls_ulonglong.c, + testsuite/libffi.call/return_ll1.c, + testsuite/libffi.call/stret_medium2.c: Fix printf format + specifiers. + testsuite/libffi.special/unwindtest.cc: include stdint.h. + +2009-06-11 Timothy Wall + + * Makefile.am, + configure.ac, + include/ffi.h.in, + include/ffi_common.h, + src/closures.c, + src/dlmalloc.c, + src/x86/ffi.c, + src/x86/ffitarget.h, + src/x86/win64.S (new), + README: Added win64 support (mingw or MSVC) + * Makefile.in, + include/Makefile.in, + man/Makefile.in, + testsuite/Makefile.in, + configure, + aclocal.m4: Regenerated + * ltcf-c.sh: properly escape cygwin/w32 path + * man/ffi_call.3: Clarify size requirements for return value. + * src/x86/ffi64.c: Fix filename in comment. + * src/x86/win32.S: Remove unused extern. + + * testsuite/libffi.call/closure_fn0.c, + testsuite/libffi.call/closure_fn1.c, + testsuite/libffi.call/closure_fn2.c, + testsuite/libffi.call/closure_fn3.c, + testsuite/libffi.call/closure_fn4.c, + testsuite/libffi.call/closure_fn5.c, + testsuite/libffi.call/closure_fn6.c, + testsuite/libffi.call/closure_stdcall.c, + testsuite/libffi.call/cls_12byte.c, + testsuite/libffi.call/cls_16byte.c, + testsuite/libffi.call/cls_18byte.c, + testsuite/libffi.call/cls_19byte.c, + testsuite/libffi.call/cls_1_1byte.c, + testsuite/libffi.call/cls_20byte.c, + testsuite/libffi.call/cls_20byte1.c, + testsuite/libffi.call/cls_24byte.c, + testsuite/libffi.call/cls_2byte.c, + testsuite/libffi.call/cls_3_1byte.c, + testsuite/libffi.call/cls_3byte1.c, + testsuite/libffi.call/cls_3byte2.c, + testsuite/libffi.call/cls_4_1byte.c, + testsuite/libffi.call/cls_4byte.c, + testsuite/libffi.call/cls_5_1_byte.c, + testsuite/libffi.call/cls_5byte.c, + testsuite/libffi.call/cls_64byte.c, + testsuite/libffi.call/cls_6_1_byte.c, + testsuite/libffi.call/cls_6byte.c, + testsuite/libffi.call/cls_7_1_byte.c, + testsuite/libffi.call/cls_7byte.c, + testsuite/libffi.call/cls_8byte.c, + testsuite/libffi.call/cls_9byte1.c, + testsuite/libffi.call/cls_9byte2.c, + testsuite/libffi.call/cls_align_double.c, + testsuite/libffi.call/cls_align_float.c, + testsuite/libffi.call/cls_align_longdouble.c, + testsuite/libffi.call/cls_align_longdouble_split.c, + testsuite/libffi.call/cls_align_longdouble_split2.c, + testsuite/libffi.call/cls_align_pointer.c, + testsuite/libffi.call/cls_align_sint16.c, + testsuite/libffi.call/cls_align_sint32.c, + testsuite/libffi.call/cls_align_sint64.c, + testsuite/libffi.call/cls_align_uint16.c, + testsuite/libffi.call/cls_align_uint32.c, + testsuite/libffi.call/cls_align_uint64.c, + testsuite/libffi.call/cls_dbls_struct.c, + testsuite/libffi.call/cls_double.c, + testsuite/libffi.call/cls_double_va.c, + testsuite/libffi.call/cls_float.c, + testsuite/libffi.call/cls_longdouble.c, + testsuite/libffi.call/cls_longdouble_va.c, + testsuite/libffi.call/cls_multi_schar.c, + testsuite/libffi.call/cls_multi_sshort.c, + testsuite/libffi.call/cls_multi_sshortchar.c, + testsuite/libffi.call/cls_multi_uchar.c, + testsuite/libffi.call/cls_multi_ushort.c, + testsuite/libffi.call/cls_multi_ushortchar.c, + testsuite/libffi.call/cls_pointer.c, + testsuite/libffi.call/cls_pointer_stack.c, + testsuite/libffi.call/cls_schar.c, + testsuite/libffi.call/cls_sint.c, + testsuite/libffi.call/cls_sshort.c, + testsuite/libffi.call/cls_uchar.c, + testsuite/libffi.call/cls_uint.c, + testsuite/libffi.call/cls_ulonglong.c, + testsuite/libffi.call/cls_ushort.c, + testsuite/libffi.call/err_bad_abi.c, + testsuite/libffi.call/err_bad_typedef.c, + testsuite/libffi.call/float2.c, + testsuite/libffi.call/huge_struct.c, + testsuite/libffi.call/nested_struct.c, + testsuite/libffi.call/nested_struct1.c, + testsuite/libffi.call/nested_struct10.c, + testsuite/libffi.call/nested_struct2.c, + testsuite/libffi.call/nested_struct3.c, + testsuite/libffi.call/nested_struct4.c, + testsuite/libffi.call/nested_struct5.c, + testsuite/libffi.call/nested_struct6.c, + testsuite/libffi.call/nested_struct7.c, + testsuite/libffi.call/nested_struct8.c, + testsuite/libffi.call/nested_struct9.c, + testsuite/libffi.call/problem1.c, + testsuite/libffi.call/return_ldl.c, + testsuite/libffi.call/return_ll1.c, + testsuite/libffi.call/stret_large.c, + testsuite/libffi.call/stret_large2.c, + testsuite/libffi.call/stret_medium.c, + testsuite/libffi.call/stret_medium2.c, + testsuite/libffi.special/unwindtest.cc: use ffi_closure_alloc instead + of checking for MMAP. Use intptr_t instead of long casts. + +2009-06-04 Andrew Haley + + * src/powerpc/ffitarget.h: Fix misapplied merge from gcc. + +2009-06-04 Andrew Haley + + * src/mips/o32.S, + src/mips/n32.S: Fix licence formatting. + +2009-06-04 Andrew Haley + + * src/x86/darwin.S: Fix licence formatting. + src/x86/win32.S: Likewise. + src/sh64/sysv.S: Likewise. + src/sh/sysv.S: Likewise. + +2009-06-04 Andrew Haley + + * src/sh64/ffi.c: Remove lint directives. Was missing from merge + of Andreas Tobler's patch from 2006-04-22. + +2009-06-04 Andrew Haley + + * src/sh/ffi.c: Apply missing hunk from Alexandre Oliva's patch of + 2007-03-07. + +2008-12-26 Timothy Wall + + * testsuite/libffi.call/cls_longdouble.c, + testsuite/libffi.call/cls_longdouble_va.c, + testsuite/libffi.call/cls_align_longdouble.c, + testsuite/libffi.call/cls_align_longdouble_split.c, + testsuite/libffi.call/cls_align_longdouble_split2.c: mark expected + failures on x86_64 cygwin/mingw. + +2008-12-22 Timothy Wall + + * testsuite/libffi.call/closure_fn0.c, + testsuite/libffi.call/closure_fn1.c, + testsuite/libffi.call/closure_fn2.c, + testsuite/libffi.call/closure_fn3.c, + testsuite/libffi.call/closure_fn4.c, + testsuite/libffi.call/closure_fn5.c, + testsuite/libffi.call/closure_fn6.c, + testsuite/libffi.call/closure_loc_fn0.c, + testsuite/libffi.call/closure_stdcall.c, + testsuite/libffi.call/cls_align_pointer.c, + testsuite/libffi.call/cls_pointer.c, + testsuite/libffi.call/cls_pointer_stack.c: use portable cast from + pointer to integer (intptr_t). + * testsuite/libffi.call/cls_longdouble.c: disable for win64. + +2008-12-19 Anthony Green + + * configure.ac: Bump version to 3.0.8. + * configure, doc/stamp-vti, doc/version.texi: Rebuilt. + * libtool-version: Increment revision. + * README: Update for new release. + +2008-11-11 Anthony Green + + * configure.ac: Bump version to 3.0.7. + * configure, doc/stamp-vti, doc/version.texi: Rebuilt. + * libtool-version: Increment revision. + * README: Update for new release. + +2008-08-25 Andreas Tobler + + * src/powerpc/ffitarget.h (ffi_abi): Add FFI_LINUX and + FFI_LINUX_SOFT_FLOAT to the POWERPC_FREEBSD enum. + Add note about flag bits used for FFI_SYSV_TYPE_SMALL_STRUCT. + Adjust copyright notice. + * src/powerpc/ffi.c: Add two new flags to indicate if we have one + register or two register to use for FFI_SYSV structs. + (ffi_prep_cif_machdep): Pass the right register flag introduced above. + (ffi_closure_helper_SYSV): Fix the return type for + FFI_SYSV_TYPE_SMALL_STRUCT. Comment. + Adjust copyright notice. + +2008-07-24 Anthony Green + + * testsuite/libffi.call/cls_dbls_struct.c, + testsuite/libffi.call/cls_double_va.c, + testsuite/libffi.call/cls_longdouble.c, + testsuite/libffi.call/cls_longdouble_va.c, + testsuite/libffi.call/cls_pointer.c, + testsuite/libffi.call/cls_pointer_stack.c, + testsuite/libffi.call/err_bad_abi.c: Clean up failures from + compiler warnings. + +2008-07-17 Anthony Green + + * configure.ac: Bump version to 3.0.6. + * configure, doc/stamp-vti, doc/version.texi: Rebuilt. + * libtool-version: Increment revision. Add documentation. + * README: Update for new release. + +2008-07-16 Kaz Kojima + + * src/sh/ffi.c (ffi_prep_closure_loc): Turn INSN into an unsigned + int. + +2008-07-16 Kaz Kojima + + * src/sh/sysv.S: Add .note.GNU-stack on Linux. + * src/sh64/sysv.S: Likewise. + +2008-04-03 Anthony Green + + * libffi.pc.in (Libs): Add -L${libdir}. + * configure.ac: Bump version to 3.0.5. + * configure, doc/stamp-vti, doc/version.texi: Rebuilt. + * libtool-version: Increment revision. + * README: Update for new release. + +2008-04-03 Anthony Green + Xerces Ranby + + * include/ffi.h.in: Wrap definition of target architecture to + protect from double definitions. + +2008-03-22 Moriyoshi Koizumi + + * src/x86/ffi.c (ffi_prep_closure_loc): Fix for bug revealed in + closure_loc_fn0.c. + * testsuite/libffi.call/closure_loc_fn0.c (closure_loc_test_fn0): + New test. + +2008-03-04 Anthony Green + Blake Chaffin + hos@tamanegi.org + + * testsuite/libffi.call/cls_align_longdouble_split2.c + testsuite/libffi.call/cls_align_longdouble_split.c + testsuite/libffi.call/cls_dbls_struct.c + testsuite/libffi.call/cls_double_va.c + testsuite/libffi.call/cls_longdouble.c + testsuite/libffi.call/cls_longdouble_va.c + testsuite/libffi.call/cls_pointer.c + testsuite/libffi.call/cls_pointer_stack.c + testsuite/libffi.call/err_bad_abi.c + testsuite/libffi.call/err_bad_typedef.c + testsuite/libffi.call/huge_struct.c + testsuite/libffi.call/stret_large2.c + testsuite/libffi.call/stret_large.c + testsuite/libffi.call/stret_medium2.c + testsuite/libffi.call/stret_medium.c: New tests from Apple. + +2008-02-26 Jakub Jelinek + Anthony Green + + * src/alpha/osf.S: Add .note.GNU-stack on Linux. + * src/s390/sysv.S: Likewise. + * src/powerpc/linux64.S: Likewise. + * src/powerpc/linux64_closure.S: Likewise. + * src/powerpc/ppc_closure.S: Likewise. + * src/powerpc/sysv.S: Likewise. + * src/x86/unix64.S: Likewise. + * src/x86/sysv.S: Likewise. + * src/sparc/v8.S: Likewise. + * src/sparc/v9.S: Likewise. + * src/m68k/sysv.S: Likewise. + * src/ia64/unix.S: Likewise. + * src/arm/sysv.S: Likewise. + +2008-02-26 Anthony Green + Thomas Heller + + * src/x86/ffi.c (ffi_closure_SYSV_inner): Change C++ comment to C + comment. + +2008-02-26 Anthony Green + Thomas Heller + + * include/ffi.h.in: Change void (*)() to void (*)(void). + +2008-02-26 Anthony Green + Thomas Heller + + * src/alpha/ffi.c: Change void (*)() to void (*)(void). + src/alpha/osf.S, src/arm/ffi.c, src/frv/ffi.c, src/ia64/ffi.c, + src/ia64/unix.S, src/java_raw_api.c, src/m32r/ffi.c, + src/mips/ffi.c, src/pa/ffi.c, src/pa/hpux32.S, src/pa/linux.S, + src/powerpc/ffi.c, src/powerpc/ffi_darwin.c, src/raw_api.c, + src/s390/ffi.c, src/sh/ffi.c, src/sh64/ffi.c, src/sparc/ffi.c, + src/x86/ffi.c, src/x86/unix64.S, src/x86/darwin64.S, + src/x86/ffi64.c: Ditto. + +2008-02-24 Anthony Green + + * configure.ac: Accept openbsd*, not just openbsd. + Bump version to 3.0.4. + * configure, doc/stamp-vti, doc/version.texi: Rebuilt. + * libtool-version: Increment revision. + * README: Update for new release. + +2008-02-22 Anthony Green + + * README: Clean up list of tested platforms. + +2008-02-22 Anthony Green + + * configure.ac: Bump version to 3.0.3. + * configure, doc/stamp-vti, doc/version.texi: Rebuilt. + * libtool-version: Increment revision. + * README: Update for new release. Clean up test docs. + +2008-02-22 Bjoern Koenig + Andreas Tobler + + * configure.ac: Add amd64-*-freebsd* target. + * configure: Regenerate. + +2008-02-22 Thomas Heller + + * configure.ac: Add x86 OpenBSD support. + * configure: Rebuilt. + +2008-02-21 Thomas Heller + + * README: Change "make test" to "make check". + +2008-02-21 Anthony Green + + * configure.ac: Bump version to 3.0.2. + * configure, doc/stamp-vti, doc/version.texi: Rebuilt. + * libtool-version: Increment revision. + * README: Update for new release. + +2008-02-21 Björn König + + * src/x86/freebsd.S: New file. + * configure.ac: Add x86 FreeBSD support. + * Makefile.am: Ditto. + +2008-02-15 Anthony Green + + * configure.ac: Bump version to 3.0.1. + * configure, doc/stamp-vti, doc/version.texi: Rebuilt. + * libtool-version: Increment revision. + * README: Update for new release. + +2008-02-15 David Daney + + * src/mips/ffi.c: Remove extra '>' from include directive. + (ffi_prep_closure_loc): Use clear_location instead of tramp. + +2008-02-15 Anthony Green + + * configure.ac: Bump version to 3.0.0. + * configure, doc/stamp-vti, doc/version.texi: Rebuilt. + +2008-02-15 David Daney + + * src/mips/ffi.c (USE__BUILTIN___CLEAR_CACHE): + Define (conditionally), and use it to include cachectl.h. + (ffi_prep_closure_loc): Fix cache flushing. + * src/mips/ffitarget.h (_ABIN32, _ABI64, _ABIO32): Define. + +2008-02-15 Anthony Green + + * man/ffi_call.3, man/ffi_prep_cif.3, man/ffi.3: + Update dates and remove all references to ffi_prep_closure. + * configure.ac: Bump version to 2.99.9. + * configure, doc/stamp-vti, doc/version.texi: Rebuilt. + +2008-02-15 Anthony Green + + * man/ffi_prep_closure.3: Delete. + * man/Makefile.am (EXTRA_DIST): Remove ffi_prep_closure.3. + (man_MANS): Ditto. + * man/Makefile.in: Rebuilt. + * configure.ac: Bump version to 2.99.8. + * configure, doc/stamp-vti, doc/version.texi: Rebuilt. + +2008-02-14 Anthony Green + + * configure.ac: Bump version to 2.99.7. + * configure, doc/stamp-vti, doc/version.texi: Rebuilt. + * include/ffi.h.in LICENSE src/debug.c src/closures.c + src/ffitest.c src/s390/sysv.S src/s390/ffitarget.h + src/types.c src/m68k/ffitarget.h src/raw_api.c src/frv/ffi.c + src/frv/ffitarget.h src/sh/ffi.c src/sh/sysv.S + src/sh/ffitarget.h src/powerpc/ffitarget.h src/pa/ffi.c + src/pa/ffitarget.h src/pa/linux.S src/java_raw_api.c + src/cris/ffitarget.h src/x86/ffi.c src/x86/sysv.S + src/x86/unix64.S src/x86/win32.S src/x86/ffitarget.h + src/x86/ffi64.c src/x86/darwin.S src/ia64/ffi.c + src/ia64/ffitarget.h src/ia64/ia64_flags.h src/ia64/unix.S + src/sparc/ffi.c src/sparc/v9.S src/sparc/ffitarget.h + src/sparc/v8.S src/alpha/ffi.c src/alpha/ffitarget.h + src/alpha/osf.S src/sh64/ffi.c src/sh64/sysv.S + src/sh64/ffitarget.h src/mips/ffi.c src/mips/ffitarget.h + src/mips/n32.S src/mips/o32.S src/arm/ffi.c src/arm/sysv.S + src/arm/ffitarget.h src/prep_cif.c: Update license text. + +2008-02-14 Anthony Green + + * README: Update tested platforms. + * configure.ac: Bump version to 2.99.6. + * configure: Rebuilt. + +2008-02-14 Anthony Green + + * configure.ac: Bump version to 2.99.5. + * configure: Rebuilt. + * Makefile.am (EXTRA_DIST): Add darwin64.S + * Makefile.in: Rebuilt. + * testsuite/lib/libffi-dg.exp: Remove libstdc++ bits from GCC tree. + * LICENSE: Update WARRANTY. + +2008-02-14 Anthony Green + + * libffi.pc.in (libdir): Fix libdir definition. + * configure.ac: Bump version to 2.99.4. + * configure: Rebuilt. + +2008-02-14 Anthony Green + + * README: Update. + * libffi.info: New file. + * doc/stamp-vti: New file. + * configure.ac: Bump version to 2.99.3. + * configure: Rebuilt. + +2008-02-14 Anthony Green + + * Makefile.am (SUBDIRS): Add man dir. + * Makefile.in: Rebuilt. + * configure.ac: Create Makefile. + * configure: Rebuilt. + * man/ffi_call.3 man/ffi_prep_cif.3 man/ffi_prep_closure.3 + man/Makefile.am man/Makefile.in: New files. + +2008-02-14 Tom Tromey + + * aclocal.m4, Makefile.in, configure, fficonfig.h.in: Rebuilt. + * mdate-sh, texinfo.tex: New files. + * Makefile.am (info_TEXINFOS): New variable. + * doc/libffi.texi: New file. + * doc/version.texi: Likewise. + +2008-02-14 Anthony Green + + * Makefile.am (AM_CFLAGS): Don't compile with -D$(TARGET). + (lib_LTLIBRARIES): Define. + (toolexeclib_LIBRARIES): Undefine. + * Makefile.in: Rebuilt. + * configure.ac: Reset version to 2.99.1. + * configure.in: Rebuilt. + +2008-02-14 Anthony Green + + * libffi.pc.in: Use @PACKAGE_NAME@ and @PACKAGE_VERSION@. + * configure.ac: Reset version to 2.99.1. + * configure.in: Rebuilt. + * Makefile.am (EXTRA_DIST): Add ChangeLog.libffi. + * Makefile.in: Rebuilt. + * LICENSE: Update copyright notice. + +2008-02-14 Anthony Green + + * include/Makefile.am (nodist_includes_HEADERS): Define. Don't + distribute ffitarget.h or ffi.h from the build include dir. + * Makefile.in: Rebuilt. + +2008-02-14 Anthony Green + + * include/Makefile.am (includesdir): Install headers under libdir. + (pkgconfigdir): Define. Install libffi.pc. + * include/Makefile.in: Rebuilt. + * libffi.pc.in: Create. + * libtool-version: Increment CURRENT + * configure.ac: Add libffi.pc.in + * configure: Rebuilt. + +2008-02-03 Anthony Green + + * include/Makefile.am (includesdir): Fix header install with + DESTDIR. + * include/Makefile.in: Rebuilt. + +2008-02-03 Timothy Wall + + * src/x86/ffi.c (FFI_INIT_TRAMPOLINE_STDCALL): Calculate jump return + offset based on code pointer, not data pointer. + +2008-02-01 Anthony Green + + * include/Makefile.am: Fix header installs. + * Makefile.am: Ditto. + * include/Makefile.in: Rebuilt. + * Makefile.in: Ditto. + +2008-02-01 Anthony Green + + * src/x86/ffi.c (FFI_INIT_TRAMPOLINE_STDCALL, + FFI_INIT_TRAMPOLINE): Revert my broken changes to twall's last + patch. + +2008-01-31 Anthony Green + + * Makefile.am (EXTRA_DIST): Add missing files. + * testsuite/Makefile.am: Ditto. + * Makefile.in, testsuite/Makefile.in: Rebuilt. + +2008-01-31 Timothy Wall + + * testsuite/libffi.call/closure_stdcall.c: Add test for stdcall + closures. + * src/x86/ffitarget.h: Increase size of trampoline for stdcall + closures. + * src/x86/win32.S: Add assembly for stdcall closure. + * src/x86/ffi.c: Initialize stdcall closure trampoline. + +2008-01-30 H.J. Lu + + PR libffi/34612 + * src/x86/sysv.S (ffi_closure_SYSV): Pop 4 byte from stack when + returning struct. + + * testsuite/libffi.call/call.exp: Add "-O2 -fomit-frame-pointer" + tests. + +2008-01-30 Anthony Green + + * Makefile.am, include/Makefile.am: Move headers to + libffi_la_SOURCES for new automake. + * Makefile.in, include/Makefile.in: Rebuilt. + + * testsuite/lib/wrapper.exp: Copied from gcc tree to allow for + execution outside of gcc tree. + * testsuite/lib/target-libpath.exp: Ditto. + + * testsuite/lib/libffi-dg.exp: Many changes to allow for execution + outside of gcc tree. + diff --git a/libffi/Makefile.am b/libffi/Makefile.am index 23e002e..cda4670 100644 --- a/libffi/Makefile.am +++ b/libffi/Makefile.am @@ -1,36 +1,45 @@ ## Process this with automake to create Makefile.in AUTOMAKE_OPTIONS = foreign subdir-objects -ACLOCAL_AMFLAGS = -I .. -I ../config SUBDIRS = include testsuite man -EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj configure.host \ - src/alpha/ffi.c src/alpha/osf.S src/alpha/ffitarget.h \ - src/arm/ffi.c src/arm/sysv.S src/arm/ffitarget.h \ - src/avr32/ffi.c src/avr32/sysv.S src/avr32/ffitarget.h \ - src/cris/ffi.c src/cris/sysv.S src/cris/ffitarget.h \ - src/ia64/ffi.c src/ia64/ffitarget.h src/ia64/ia64_flags.h \ - src/ia64/unix.S \ - src/mips/ffi.c src/mips/n32.S src/mips/o32.S \ - src/mips/ffitarget.h \ - src/m32r/ffi.c src/m32r/sysv.S src/m32r/ffitarget.h \ - src/m68k/ffi.c src/m68k/sysv.S src/m68k/ffitarget.h \ - src/powerpc/ffi.c src/powerpc/sysv.S \ - src/powerpc/linux64.S src/powerpc/linux64_closure.S \ - src/powerpc/ppc_closure.S src/powerpc/asm.h \ - src/powerpc/aix.S src/powerpc/darwin.S \ - src/powerpc/aix_closure.S src/powerpc/darwin_closure.S \ - src/powerpc/ffi_darwin.c src/powerpc/ffitarget.h \ - src/s390/ffi.c src/s390/sysv.S src/s390/ffitarget.h \ - src/sh/ffi.c src/sh/sysv.S src/sh/ffitarget.h \ - src/sh64/ffi.c src/sh64/sysv.S src/sh64/ffitarget.h \ - src/sparc/v8.S src/sparc/v9.S src/sparc/ffitarget.h \ - src/sparc/ffi.c src/x86/darwin64.S \ - src/x86/ffi.c src/x86/sysv.S src/x86/win32.S src/x86/darwin.S \ - src/x86/ffi64.c src/x86/unix64.S src/x86/ffitarget.h \ - src/pa/ffitarget.h src/pa/ffi.c src/pa/linux.S src/pa/hpux32.S \ - src/frv/ffi.c src/frv/eabi.S src/frv/ffitarget.h src/dlmalloc.c +EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj configure.host \ + src/aarch64/ffi.c src/aarch64/ffitarget.h \ + src/alpha/ffi.c src/alpha/osf.S src/alpha/ffitarget.h \ + src/arm/ffi.c src/arm/sysv.S src/arm/ffitarget.h \ + src/avr32/ffi.c src/avr32/sysv.S src/avr32/ffitarget.h \ + src/cris/ffi.c src/cris/sysv.S src/cris/ffitarget.h \ + src/ia64/ffi.c src/ia64/ffitarget.h src/ia64/ia64_flags.h \ + src/ia64/unix.S src/mips/ffi.c src/mips/n32.S src/mips/o32.S \ + src/mips/ffitarget.h src/m32r/ffi.c src/m32r/sysv.S \ + src/m32r/ffitarget.h src/m68k/ffi.c src/m68k/sysv.S \ + src/m68k/ffitarget.h src/powerpc/ffi.c src/powerpc/sysv.S \ + src/powerpc/linux64.S src/powerpc/linux64_closure.S \ + src/powerpc/ppc_closure.S src/powerpc/asm.h \ + src/powerpc/aix.S src/powerpc/darwin.S \ + src/powerpc/aix_closure.S src/powerpc/darwin_closure.S \ + src/powerpc/ffi_darwin.c src/powerpc/ffitarget.h \ + src/s390/ffi.c src/s390/sysv.S src/s390/ffitarget.h \ + src/sh/ffi.c src/sh/sysv.S src/sh/ffitarget.h src/sh64/ffi.c \ + src/sh64/sysv.S src/sh64/ffitarget.h src/sparc/v8.S \ + src/sparc/v9.S src/sparc/ffitarget.h src/sparc/ffi.c \ + src/x86/darwin64.S src/x86/ffi.c src/x86/sysv.S \ + src/x86/win32.S src/x86/darwin.S src/x86/win64.S \ + src/x86/freebsd.S src/x86/ffi64.c src/x86/unix64.S \ + src/x86/ffitarget.h src/pa/ffitarget.h src/pa/ffi.c \ + src/pa/linux.S src/pa/hpux32.S src/frv/ffi.c src/bfin/ffi.c \ + src/bfin/ffitarget.h src/bfin/sysv.S src/frv/eabi.S \ + src/frv/ffitarget.h src/dlmalloc.c src/tile/ffi.c \ + src/tile/ffitarget.h src/tile/tile.S libtool-version \ + ChangeLog.libffi m4/libtool.m4 m4/lt~obsolete.m4 \ + m4/ltoptions.m4 m4/ltsugar.m4 m4/ltversion.m4 \ + m4/ltversion.m4 src/arm/gentramp.sh src/debug.c msvcc.sh \ + generate-ios-source-and-headers.py \ + generate-osx-source-and-headers.py \ + libffi.xcodeproj/project.pbxproj src/arm/trampoline.S + +info_TEXINFOS = doc/libffi.texi ## ################################################################ @@ -84,14 +93,21 @@ MAKEOVERRIDES= toolexeclib_LTLIBRARIES = libffi.la noinst_LTLIBRARIES = libffi_convenience.la -libffi_la_SOURCES = src/debug.c src/prep_cif.c src/types.c \ +libffi_la_SOURCES = src/prep_cif.c src/types.c \ src/raw_api.c src/java_raw_api.c src/closures.c nodist_libffi_la_SOURCES = +if FFI_DEBUG +nodist_libffi_la_SOURCES += src/debug.c +endif + if MIPS nodist_libffi_la_SOURCES += src/mips/ffi.c src/mips/o32.S src/mips/n32.S endif +if BFIN +nodist_libffi_la_SOURCES += src/bfin/ffi.c src/bfin/sysv.S +endif if X86 nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/sysv.S endif @@ -134,8 +150,14 @@ endif if POWERPC_FREEBSD nodist_libffi_la_SOURCES += src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S endif +if AARCH64 +nodist_libffi_la_SOURCES += src/aarch64/sysv.S src/aarch64/ffi.c +endif if ARM nodist_libffi_la_SOURCES += src/arm/sysv.S src/arm/ffi.c +if FFI_EXEC_TRAMPOLINE_TABLE +nodist_libffi_la_SOURCES += src/arm/trampoline.S +endif endif if AVR32 nodist_libffi_la_SOURCES += src/avr32/sysv.S src/avr32/ffi.c @@ -164,6 +186,9 @@ endif if PA_HPUX nodist_libffi_la_SOURCES += src/pa/hpux32.S src/pa/ffi.c endif +if TILE +nodist_libffi_la_SOURCES += src/tile/tile.S src/tile/ffi.c +endif libffi_convenience_la_SOURCES = $(libffi_la_SOURCES) nodist_libffi_convenience_la_SOURCES = $(nodist_libffi_la_SOURCES) diff --git a/libffi/README b/libffi/README index 1da4e89..a0fb717 100644 --- a/libffi/README +++ b/libffi/README @@ -1,8 +1,8 @@ Status ====== -libffi-3.0.11 was released on *****************. Check the libffi web -page for updates: . +libffi-3.0.12 was released on XXXXXXX. Check the libffi web page for +updates: . What is libffi? @@ -48,48 +48,52 @@ refer to the wiki page here: At the time of release, the following basic configurations have been tested: -|--------------+------------------| -| Architecture | Operating System | -|--------------+------------------| -| Alpha | Linux | -| Alpha | Tru64 | -| ARM | Linux | -| ARM | iOS | -| AVR32 | Linux | -| HPPA | HPUX | -| IA-64 | Linux | -| M68K | RTEMS | -| MIPS | IRIX | -| MIPS | Linux | -| MIPS | RTEMS | -| MIPS64 | Linux | -| PowerPC | AMIGA | -| PowerPC | Linux | -| PowerPC | Mac OSX | -| PowerPC | FreeBSD | -| PowerPC64 | Linux | -| S390 | Linux | -| S390X | Linux | -| SPARC | Linux | -| SPARC | Solaris | -| SPARC64 | Linux | -| SPARC64 | FreeBSD | -| X86 | FreeBSD | -| X86 | Interix | -| X86 | kFreeBSD | -| X86 | Linux | -| X86 | Linux/x32 | -| X86 | Mac OSX | -| X86 | OpenBSD | -| X86 | OS/2 | -| X86 | Solaris | -| X86 | Windows/Cygwin | -| X86 | Windows/MingW | -| X86-64 | FreeBSD | -| X86-64 | Linux | -| X86-64 | OpenBSD | -| X86-64 | Windows/MingW | -|--------------+------------------| +|-----------------+------------------| +| Architecture | Operating System | +|-----------------+------------------| +| AArch64 | Linux | +| Alpha | Linux | +| Alpha | Tru64 | +| ARM | Linux | +| ARM | iOS | +| AVR32 | Linux | +| Blackfin | uClinux | +| HPPA | HPUX | +| IA-64 | Linux | +| M68K | FreeMiNT | +| M68K | RTEMS | +| MIPS | IRIX | +| MIPS | Linux | +| MIPS | RTEMS | +| MIPS64 | Linux | +| PowerPC | AMIGA | +| PowerPC | Linux | +| PowerPC | Mac OSX | +| PowerPC | FreeBSD | +| PowerPC64 | Linux | +| S390 | Linux | +| S390X | Linux | +| SPARC | Linux | +| SPARC | Solaris | +| SPARC64 | Linux | +| SPARC64 | FreeBSD | +| TILE-Gx/TILEPro | Linux | +| X86 | FreeBSD | +| X86 | Interix | +| X86 | kFreeBSD | +| X86 | Linux | +| X86 | Mac OSX | +| X86 | OpenBSD | +| X86 | OS/2 | +| X86 | Solaris | +| X86 | Windows/Cygwin | +| X86 | Windows/MingW | +| X86-64 | FreeBSD | +| X86-64 | Linux | +| X86-64 | Linux/x32 | +| X86-64 | OpenBSD | +| X86-64 | Windows/MingW | +|-----------------+------------------| Please send additional platform test results to libffi-discuss@sourceware.org and feel free to update the wiki page @@ -128,7 +132,7 @@ under a MingW environment, you may need to remove the line in configure that sets 'fix_srcfile_path' to a 'cygpath' command. ('cygpath' is not present in MingW, and is not required when using MingW-style paths.) -For iOS builds, refer to the build-ios.sh script for guidance. +For iOS builds, the 'libffi.xcodeproj' Xcode project is available. Configure has many other options. Use "configure --help" to see them all. @@ -146,13 +150,24 @@ History See the ChangeLog files for details. -3.0.11 MMM-DD-YY +3.0.12 XXX-XX-XX + Add Blackfin support. + Add TILE-Gx/TILEPro support. + Add AArch64 support. + Add support for PaX enabled kernels with MPROTECT. + +3.0.11 Apr-11-12 Lots of build fixes. - Add Amiga newer MacOS support. + Add Amiga newer MacOS support. + Add support for variadic functions (ffi_prep_cif_var). Add Linux/x32 support. - Add thiscall and fastcall support on Windows. + Add thiscall, fastcall and MSVC cdecl support on Windows. + Add Amiga and newer MacOS support. + Add m68k FreeMiNT support. + Integration with iOS' xcode build tools. Fix Octeon and MC68881 support. Fix code pessimizations. + Lots of build fixes. 3.0.10 Aug-23-11 Add support for Apple's iOS. @@ -311,8 +326,10 @@ Thorup. Major processor architecture ports were contributed by the following developers: +aarch64 Marcus Shawcroft, James Greenhalgh alpha Richard Henderson arm Raffaele Sena +blackfin Alexandre Keunecke I. de Mendonca cris Simon Posnjak, Hans-Peter Nilsson frv Anthony Green ia64 Hans Boehm @@ -328,6 +345,7 @@ s390 Gerhard Tonn, Ulrich Weigand sh Kaz Kojima sh64 Kaz Kojima sparc Anthony Green, Gordon Irlam +tile-gx/tilepro Walter Lee x86 Anthony Green, Jon Beniston x86-64 Bo Thorsen diff --git a/libffi/configure b/libffi/configure index 24b9f41..706bd19 100755 --- a/libffi/configure +++ b/libffi/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.64 for libffi 3.0.9. +# Generated by GNU Autoconf 2.64 for libffi 3.0.11. # # Report bugs to . # @@ -559,8 +559,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='libffi' PACKAGE_TARNAME='libffi' -PACKAGE_VERSION='3.0.9' -PACKAGE_STRING='libffi 3.0.9' +PACKAGE_VERSION='3.0.11' +PACKAGE_STRING='libffi 3.0.11' PACKAGE_BUGREPORT='http://gcc.gnu.org/bugs.html' PACKAGE_URL='' @@ -606,10 +606,17 @@ LTLIBOBJS LIBOBJS toolexeclibdir toolexecdir +FFI_DEBUG_FALSE +FFI_DEBUG_TRUE TARGETDIR TARGET +FFI_EXEC_TRAMPOLINE_TABLE +FFI_EXEC_TRAMPOLINE_TABLE_FALSE +FFI_EXEC_TRAMPOLINE_TABLE_TRUE HAVE_LONG_DOUBLE ALLOCA +TILE_FALSE +TILE_TRUE PA64_HPUX_FALSE PA64_HPUX_TRUE PA_HPUX_FALSE @@ -632,6 +639,8 @@ AVR32_FALSE AVR32_TRUE ARM_FALSE ARM_TRUE +AARCH64_FALSE +AARCH64_TRUE POWERPC_FREEBSD_FALSE POWERPC_FREEBSD_TRUE POWERPC_DARWIN_FALSE @@ -660,6 +669,8 @@ X86_FALSE X86_TRUE SPARC_FALSE SPARC_TRUE +BFIN_FALSE +BFIN_TRUE MIPS_FALSE MIPS_TRUE AM_LTLDFLAGS @@ -795,6 +806,7 @@ enable_fast_install with_gnu_ld enable_libtool_lock enable_maintainer_mode +enable_pax_emutramp enable_debug enable_structs enable_raw_api @@ -1348,7 +1360,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures libffi 3.0.9 to adapt to many kinds of systems. +\`configure' configures libffi 3.0.11 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1419,7 +1431,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of libffi 3.0.9:";; + short | recursive ) echo "Configuration of libffi 3.0.11:";; esac cat <<\_ACEOF @@ -1437,6 +1449,7 @@ Optional Features: --disable-libtool-lock avoid locking (might break parallel builds) --enable-maintainer-mode enable make rules and dependencies not useful (and sometimes confusing) to the casual installer + --enable-pax_emutramp enable pax emulated trampolines, for we can't use PROT_EXEC --enable-debug debugging mode --disable-structs omit code for struct support --disable-raw-api make the raw api unavailable @@ -1527,7 +1540,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -libffi configure 3.0.9 +libffi configure 3.0.11 generated by GNU Autoconf 2.64 Copyright (C) 2009 Free Software Foundation, Inc. @@ -2076,7 +2089,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by libffi $as_me 3.0.9, which was +It was created by libffi $as_me 3.0.11, which was generated by GNU Autoconf 2.64. Invocation command line was $ $0 $@ @@ -3043,7 +3056,7 @@ fi # Define the identity of the package. PACKAGE='libffi' - VERSION='3.0.9' + VERSION='3.0.11' cat >>confdefs.h <<_ACEOF @@ -10774,7 +10787,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 10777 "configure" +#line 10790 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -10880,7 +10893,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 10883 "configure" +#line 10896 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11318,6 +11331,10 @@ fi TARGETDIR="unknown" case "$host" in + aarch64*-*-*) + TARGET=AARCH64; TARGETDIR=aarch64 + ;; + alpha*-*-*) TARGET=ALPHA; TARGETDIR=alpha; # Support 128-bit long double, changeable via command-line switch. @@ -11330,12 +11347,20 @@ case "$host" in amd64-*-freebsd* | amd64-*-openbsd*) TARGET=X86_64; TARGETDIR=x86 + ;; + + amd64-*-freebsd*) + TARGET=X86_64; TARGETDIR=x86 ;; avr32*-*-*) TARGET=AVR32; TARGETDIR=avr32 ;; + bfin*) + TARGET=BFIN; TARGETDIR=bfin + ;; + cris-*-*) TARGET=LIBFFI_CRIS; TARGETDIR=cris ;; @@ -11344,7 +11369,7 @@ case "$host" in TARGET=FRV; TARGETDIR=frv ;; - hppa*-*-linux* | parisc*-*-linux*) + hppa*-*-linux* | parisc*-*-linux* | hppa*-*-openbsd*) TARGET=PA_LINUX; TARGETDIR=pa ;; hppa*64-*-hpux*) @@ -11357,7 +11382,7 @@ case "$host" in i?86-*-freebsd* | i?86-*-openbsd*) TARGET=X86_FREEBSD; TARGETDIR=x86 ;; - i?86-win32* | i?86-*-cygwin* | i?86-*-mingw* | i?86-*-os2*) + i?86-win32* | i?86-*-cygwin* | i?86-*-mingw* | i?86-*-os2* | i?86-*-interix*) TARGET=X86_WIN32; TARGETDIR=x86 # All mingw/cygwin/win32 builds require -no-undefined for sharedlib. # We must also check with_cross_host to decide if this is a native @@ -11394,7 +11419,7 @@ case "$host" in mips-sgi-irix5.* | mips-sgi-irix6.* | mips*-*-rtems*) TARGET=MIPS; TARGETDIR=mips ;; - mips*-*-linux*) + mips*-*-linux* | mips*-*-openbsd*) # Support 128-bit long double for NewABI. HAVE_LONG_DOUBLE='defined(__mips64)' TARGET=MIPS; TARGETDIR=mips @@ -11403,19 +11428,22 @@ case "$host" in powerpc*-*-linux* | powerpc-*-sysv*) TARGET=POWERPC; TARGETDIR=powerpc ;; + powerpc-*-amigaos*) + TARGET=POWERPC; TARGETDIR=powerpc + ;; powerpc-*-beos*) TARGET=POWERPC; TARGETDIR=powerpc ;; - powerpc-*-darwin*) + powerpc-*-darwin* | powerpc64-*-darwin*) TARGET=POWERPC_DARWIN; TARGETDIR=powerpc ;; powerpc-*-aix* | rs6000-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc ;; - powerpc-*-freebsd*) + powerpc-*-freebsd* | powerpc-*-openbsd*) TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc ;; - powerpc64-*-freebsd*) + powerpc64-*-freebsd*) TARGET=POWERPC; TARGETDIR=powerpc ;; powerpc*-*-rtems*) @@ -11437,6 +11465,10 @@ case "$host" in TARGET=SPARC; TARGETDIR=sparc ;; + tile*-*) + TARGET=TILE; TARGETDIR=tile + ;; + x86_64-*-darwin*) TARGET=X86_DARWIN; TARGETDIR=x86 ;; @@ -11474,6 +11506,14 @@ else MIPS_FALSE= fi + if test x$TARGET = xBFIN; then + BFIN_TRUE= + BFIN_FALSE='#' +else + BFIN_TRUE='#' + BFIN_FALSE= +fi + if test x$TARGET = xSPARC; then SPARC_TRUE= SPARC_FALSE='#' @@ -11586,6 +11626,14 @@ else POWERPC_FREEBSD_FALSE= fi + if test x$TARGET = xAARCH64; then + AARCH64_TRUE= + AARCH64_FALSE='#' +else + AARCH64_TRUE='#' + AARCH64_FALSE= +fi + if test x$TARGET = xARM; then ARM_TRUE= ARM_FALSE='#' @@ -11674,6 +11722,14 @@ else PA64_HPUX_FALSE= fi + if test x$TARGET = xTILE; then + TILE_TRUE= + TILE_FALSE='#' +else + TILE_TRUE='#' + TILE_FALSE= +fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } @@ -12501,13 +12557,40 @@ $as_echo "#define HAVE_AS_STRING_PSEUDO_OP 1" >>confdefs.h fi fi +# On PaX enable kernels that have MPROTECT enable we can't use PROT_EXEC. +# Check whether --enable-pax_emutramp was given. +if test "${enable_pax_emutramp+set}" = set; then : + enableval=$enable_pax_emutramp; if test "$enable_pax_emutramp" = "yes"; then + +$as_echo "#define FFI_MMAP_EXEC_EMUTRAMP_PAX 1" >>confdefs.h + + fi +fi + + +FFI_EXEC_TRAMPOLINE_TABLE=0 case "$target" in - *-apple-darwin10* | *-*-freebsd* | *-*-openbsd* | *-pc-solaris*) + *arm*-apple-darwin*) + FFI_EXEC_TRAMPOLINE_TABLE=1 + +$as_echo "#define FFI_EXEC_TRAMPOLINE_TABLE 1" >>confdefs.h + + ;; + *-apple-darwin1* | *-*-freebsd* | *-*-kfreebsd* | *-*-openbsd* | *-pc-solaris*) $as_echo "#define FFI_MMAP_EXEC_WRIT 1" >>confdefs.h ;; esac + if test x$FFI_EXEC_TRAMPOLINE_TABLE = x1; then + FFI_EXEC_TRAMPOLINE_TABLE_TRUE= + FFI_EXEC_TRAMPOLINE_TABLE_FALSE='#' +else + FFI_EXEC_TRAMPOLINE_TABLE_TRUE='#' + FFI_EXEC_TRAMPOLINE_TABLE_FALSE= +fi + + if test x$TARGET = xX86_64; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler supports unwind section type" >&5 @@ -12532,67 +12615,69 @@ $as_echo "#define HAVE_AS_X86_64_UNWIND_SECTION_TYPE 1" >>confdefs.h fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether .eh_frame section should be read-only" >&5 +if test "x$GCC" = "xyes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether .eh_frame section should be read-only" >&5 $as_echo_n "checking whether .eh_frame section should be read-only... " >&6; } if test "${libffi_cv_ro_eh_frame+set}" = set; then : $as_echo_n "(cached) " >&6 else - libffi_cv_ro_eh_frame=no - echo 'extern void foo (void); void bar (void) { foo (); foo (); }' > conftest.c - if $CC $CFLAGS -S -fpic -fexceptions -o conftest.s conftest.c > /dev/null 2>&1; then - if grep '.section.*eh_frame.*"a"' conftest.s > /dev/null; then - libffi_cv_ro_eh_frame=yes - elif grep '.section.*eh_frame.*#alloc' conftest.c \ - | grep -v '#write' > /dev/null; then - libffi_cv_ro_eh_frame=yes - fi - fi - rm -f conftest.* + libffi_cv_ro_eh_frame=no + echo 'extern void foo (void); void bar (void) { foo (); foo (); }' > conftest.c + if $CC $CFLAGS -S -fpic -fexceptions -o conftest.s conftest.c > /dev/null 2>&1; then + if grep '.section.*eh_frame.*"a"' conftest.s > /dev/null; then + libffi_cv_ro_eh_frame=yes + elif grep '.section.*eh_frame.*#alloc' conftest.c \ + | grep -v '#write' > /dev/null; then + libffi_cv_ro_eh_frame=yes + fi + fi + rm -f conftest.* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $libffi_cv_ro_eh_frame" >&5 $as_echo "$libffi_cv_ro_eh_frame" >&6; } -if test "x$libffi_cv_ro_eh_frame" = xyes; then + if test "x$libffi_cv_ro_eh_frame" = xyes; then $as_echo "#define HAVE_RO_EH_FRAME 1" >>confdefs.h $as_echo "#define EH_FRAME_FLAGS \"a\"" >>confdefs.h -else + else $as_echo "#define EH_FRAME_FLAGS \"aw\"" >>confdefs.h -fi + fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __attribute__((visibility(\"hidden\")))" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __attribute__((visibility(\"hidden\")))" >&5 $as_echo_n "checking for __attribute__((visibility(\"hidden\")))... " >&6; } if test "${libffi_cv_hidden_visibility_attribute+set}" = set; then : $as_echo_n "(cached) " >&6 else - echo 'int __attribute__ ((visibility ("hidden"))) foo (void) { return 1; }' > conftest.c - libffi_cv_hidden_visibility_attribute=no - if { ac_try='${CC-cc} -Werror -S conftest.c -o conftest.s 1>&5' + echo 'int __attribute__ ((visibility ("hidden"))) foo (void) { return 1 ; }' > conftest.c + libffi_cv_hidden_visibility_attribute=no + if { ac_try='${CC-cc} -Werror -S conftest.c -o conftest.s 1>&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 (eval $ac_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then - if grep '\.hidden.*foo' conftest.s >/dev/null; then - libffi_cv_hidden_visibility_attribute=yes - fi - fi - rm -f conftest.* + if grep '\.hidden.*foo' conftest.s >/dev/null; then + libffi_cv_hidden_visibility_attribute=yes + fi + fi + rm -f conftest.* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $libffi_cv_hidden_visibility_attribute" >&5 $as_echo "$libffi_cv_hidden_visibility_attribute" >&6; } -if test $libffi_cv_hidden_visibility_attribute = yes; then + if test $libffi_cv_hidden_visibility_attribute = yes; then $as_echo "#define HAVE_HIDDEN_VISIBILITY_ATTRIBUTE 1" >>confdefs.h + fi fi @@ -12611,6 +12696,14 @@ $as_echo "#define FFI_DEBUG 1" >>confdefs.h fi fi + if test "$enable_debug" = "yes"; then + FFI_DEBUG_TRUE= + FFI_DEBUG_FALSE='#' +else + FFI_DEBUG_TRUE='#' + FFI_DEBUG_FALSE= +fi + # Check whether --enable-structs was given. if test "${enable_structs+set}" = set; then : @@ -12804,6 +12897,10 @@ if test -z "${MIPS_TRUE}" && test -z "${MIPS_FALSE}"; then as_fn_error "conditional \"MIPS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${BFIN_TRUE}" && test -z "${BFIN_FALSE}"; then + as_fn_error "conditional \"BFIN\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${SPARC_TRUE}" && test -z "${SPARC_FALSE}"; then as_fn_error "conditional \"SPARC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -12860,6 +12957,10 @@ if test -z "${POWERPC_FREEBSD_TRUE}" && test -z "${POWERPC_FREEBSD_FALSE}"; then as_fn_error "conditional \"POWERPC_FREEBSD\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${AARCH64_TRUE}" && test -z "${AARCH64_FALSE}"; then + as_fn_error "conditional \"AARCH64\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${ARM_TRUE}" && test -z "${ARM_FALSE}"; then as_fn_error "conditional \"ARM\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -12904,7 +13005,19 @@ if test -z "${PA64_HPUX_TRUE}" && test -z "${PA64_HPUX_FALSE}"; then as_fn_error "conditional \"PA64_HPUX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${TILE_TRUE}" && test -z "${TILE_FALSE}"; then + as_fn_error "conditional \"TILE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${FFI_EXEC_TRAMPOLINE_TABLE_TRUE}" && test -z "${FFI_EXEC_TRAMPOLINE_TABLE_FALSE}"; then + as_fn_error "conditional \"FFI_EXEC_TRAMPOLINE_TABLE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${FFI_DEBUG_TRUE}" && test -z "${FFI_DEBUG_FALSE}"; then + as_fn_error "conditional \"FFI_DEBUG\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi : ${CONFIG_STATUS=./config.status} ac_write_fail=0 @@ -13313,7 +13426,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by libffi $as_me 3.0.9, which was +This file was extended by libffi $as_me 3.0.11, which was generated by GNU Autoconf 2.64. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -13381,7 +13494,7 @@ Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_version="\\ -libffi config.status 3.0.9 +libffi config.status 3.0.11 configured by $0, generated by GNU Autoconf 2.64, with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" diff --git a/libffi/configure.ac b/libffi/configure.ac index 5036e25..d7ab066 100644 --- a/libffi/configure.ac +++ b/libffi/configure.ac @@ -2,7 +2,7 @@ dnl Process this with autoconf to create configure AC_PREREQ(2.64) -AC_INIT([libffi], [3.0.9], [http://gcc.gnu.org/bugs.html]) +AC_INIT([libffi], [3.0.11], [http://gcc.gnu.org/bugs.html]) AC_CONFIG_HEADERS([fficonfig.h]) AM_ENABLE_MULTILIB(, ..) @@ -41,6 +41,10 @@ AM_CONDITIONAL(TESTSUBDIR, test -d $srcdir/testsuite) TARGETDIR="unknown" case "$host" in + aarch64*-*-*) + TARGET=AARCH64; TARGETDIR=aarch64 + ;; + alpha*-*-*) TARGET=ALPHA; TARGETDIR=alpha; # Support 128-bit long double, changeable via command-line switch. @@ -53,12 +57,20 @@ case "$host" in amd64-*-freebsd* | amd64-*-openbsd*) TARGET=X86_64; TARGETDIR=x86 + ;; + + amd64-*-freebsd*) + TARGET=X86_64; TARGETDIR=x86 ;; avr32*-*-*) TARGET=AVR32; TARGETDIR=avr32 ;; + bfin*) + TARGET=BFIN; TARGETDIR=bfin + ;; + cris-*-*) TARGET=LIBFFI_CRIS; TARGETDIR=cris ;; @@ -67,7 +79,7 @@ case "$host" in TARGET=FRV; TARGETDIR=frv ;; - hppa*-*-linux* | parisc*-*-linux*) + hppa*-*-linux* | parisc*-*-linux* | hppa*-*-openbsd*) TARGET=PA_LINUX; TARGETDIR=pa ;; hppa*64-*-hpux*) @@ -80,7 +92,7 @@ case "$host" in i?86-*-freebsd* | i?86-*-openbsd*) TARGET=X86_FREEBSD; TARGETDIR=x86 ;; - i?86-win32* | i?86-*-cygwin* | i?86-*-mingw* | i?86-*-os2*) + i?86-win32* | i?86-*-cygwin* | i?86-*-mingw* | i?86-*-os2* | i?86-*-interix*) TARGET=X86_WIN32; TARGETDIR=x86 # All mingw/cygwin/win32 builds require -no-undefined for sharedlib. # We must also check with_cross_host to decide if this is a native @@ -117,7 +129,7 @@ case "$host" in mips-sgi-irix5.* | mips-sgi-irix6.* | mips*-*-rtems*) TARGET=MIPS; TARGETDIR=mips ;; - mips*-*-linux*) + mips*-*-linux* | mips*-*-openbsd*) # Support 128-bit long double for NewABI. HAVE_LONG_DOUBLE='defined(__mips64)' TARGET=MIPS; TARGETDIR=mips @@ -126,19 +138,22 @@ case "$host" in powerpc*-*-linux* | powerpc-*-sysv*) TARGET=POWERPC; TARGETDIR=powerpc ;; + powerpc-*-amigaos*) + TARGET=POWERPC; TARGETDIR=powerpc + ;; powerpc-*-beos*) TARGET=POWERPC; TARGETDIR=powerpc ;; - powerpc-*-darwin*) + powerpc-*-darwin* | powerpc64-*-darwin*) TARGET=POWERPC_DARWIN; TARGETDIR=powerpc ;; powerpc-*-aix* | rs6000-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc ;; - powerpc-*-freebsd*) + powerpc-*-freebsd* | powerpc-*-openbsd*) TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc ;; - powerpc64-*-freebsd*) + powerpc64-*-freebsd*) TARGET=POWERPC; TARGETDIR=powerpc ;; powerpc*-*-rtems*) @@ -160,6 +175,10 @@ case "$host" in TARGET=SPARC; TARGETDIR=sparc ;; + tile*-*) + TARGET=TILE; TARGETDIR=tile + ;; + x86_64-*-darwin*) TARGET=X86_DARWIN; TARGETDIR=x86 ;; @@ -190,6 +209,7 @@ if test $TARGETDIR = unknown; then fi AM_CONDITIONAL(MIPS, test x$TARGET = xMIPS) +AM_CONDITIONAL(BFIN, test x$TARGET = xBFIN) AM_CONDITIONAL(SPARC, test x$TARGET = xSPARC) AM_CONDITIONAL(X86, test x$TARGET = xX86) AM_CONDITIONAL(X86_FREEBSD, test x$TARGET = xX86_FREEBSD) @@ -204,6 +224,7 @@ AM_CONDITIONAL(POWERPC, test x$TARGET = xPOWERPC) AM_CONDITIONAL(POWERPC_AIX, test x$TARGET = xPOWERPC_AIX) AM_CONDITIONAL(POWERPC_DARWIN, test x$TARGET = xPOWERPC_DARWIN) AM_CONDITIONAL(POWERPC_FREEBSD, test x$TARGET = xPOWERPC_FREEBSD) +AM_CONDITIONAL(AARCH64, test x$TARGET = xAARCH64) AM_CONDITIONAL(ARM, test x$TARGET = xARM) AM_CONDITIONAL(AVR32, test x$TARGET = xAVR32) AM_CONDITIONAL(LIBFFI_CRIS, test x$TARGET = xLIBFFI_CRIS) @@ -215,6 +236,7 @@ AM_CONDITIONAL(SH64, test x$TARGET = xSH64) AM_CONDITIONAL(PA_LINUX, test x$TARGET = xPA_LINUX) AM_CONDITIONAL(PA_HPUX, test x$TARGET = xPA_HPUX) AM_CONDITIONAL(PA64_HPUX, test x$TARGET = xPA64_HPUX) +AM_CONDITIONAL(TILE, test x$TARGET = xTILE) AC_HEADER_STDC AC_CHECK_FUNCS(memcpy) @@ -311,13 +333,30 @@ if test x$TARGET = xX86 || test x$TARGET = xX86_WIN32 || test x$TARGET = xX86_64 fi fi +# On PaX enable kernels that have MPROTECT enable we can't use PROT_EXEC. +AC_ARG_ENABLE(pax_emutramp, + [ --enable-pax_emutramp enable pax emulated trampolines, for we can't use PROT_EXEC], + if test "$enable_pax_emutramp" = "yes"; then + AC_DEFINE(FFI_MMAP_EXEC_EMUTRAMP_PAX, 1, + [Define this if you want to enable pax emulated trampolines]) + fi) + +FFI_EXEC_TRAMPOLINE_TABLE=0 case "$target" in - *-apple-darwin10* | *-*-freebsd* | *-*-openbsd* | *-pc-solaris*) + *arm*-apple-darwin*) + FFI_EXEC_TRAMPOLINE_TABLE=1 + AC_DEFINE(FFI_EXEC_TRAMPOLINE_TABLE, 1, + [Cannot use PROT_EXEC on this target, so, we revert to + alternative means]) + ;; + *-apple-darwin1* | *-*-freebsd* | *-*-kfreebsd* | *-*-openbsd* | *-pc-solaris*) AC_DEFINE(FFI_MMAP_EXEC_WRIT, 1, [Cannot use malloc on this target, so, we revert to alternative means]) ;; esac +AM_CONDITIONAL(FFI_EXEC_TRAMPOLINE_TABLE, test x$FFI_EXEC_TRAMPOLINE_TABLE = x1) +AC_SUBST(FFI_EXEC_TRAMPOLINE_TABLE) if test x$TARGET = xX86_64; then AC_CACHE_CHECK([assembler supports unwind section type], @@ -334,44 +373,46 @@ if test x$TARGET = xX86_64; then fi fi -AC_CACHE_CHECK([whether .eh_frame section should be read-only], - libffi_cv_ro_eh_frame, [ - libffi_cv_ro_eh_frame=no - echo 'extern void foo (void); void bar (void) { foo (); foo (); }' > conftest.c - if $CC $CFLAGS -S -fpic -fexceptions -o conftest.s conftest.c > /dev/null 2>&1; then - if grep '.section.*eh_frame.*"a"' conftest.s > /dev/null; then - libffi_cv_ro_eh_frame=yes - elif grep '.section.*eh_frame.*#alloc' conftest.c \ - | grep -v '#write' > /dev/null; then - libffi_cv_ro_eh_frame=yes - fi - fi - rm -f conftest.* - ]) -if test "x$libffi_cv_ro_eh_frame" = xyes; then - AC_DEFINE(HAVE_RO_EH_FRAME, 1, - [Define if .eh_frame sections should be read-only.]) - AC_DEFINE(EH_FRAME_FLAGS, "a", - [Define to the flags needed for the .section .eh_frame directive.]) -else - AC_DEFINE(EH_FRAME_FLAGS, "aw", - [Define to the flags needed for the .section .eh_frame directive.]) -fi +if test "x$GCC" = "xyes"; then + AC_CACHE_CHECK([whether .eh_frame section should be read-only], + libffi_cv_ro_eh_frame, [ + libffi_cv_ro_eh_frame=no + echo 'extern void foo (void); void bar (void) { foo (); foo (); }' > conftest.c + if $CC $CFLAGS -S -fpic -fexceptions -o conftest.s conftest.c > /dev/null 2>&1; then + if grep '.section.*eh_frame.*"a"' conftest.s > /dev/null; then + libffi_cv_ro_eh_frame=yes + elif grep '.section.*eh_frame.*#alloc' conftest.c \ + | grep -v '#write' > /dev/null; then + libffi_cv_ro_eh_frame=yes + fi + fi + rm -f conftest.* + ]) + if test "x$libffi_cv_ro_eh_frame" = xyes; then + AC_DEFINE(HAVE_RO_EH_FRAME, 1, + [Define if .eh_frame sections should be read-only.]) + AC_DEFINE(EH_FRAME_FLAGS, "a", + [Define to the flags needed for the .section .eh_frame directive. ]) + else + AC_DEFINE(EH_FRAME_FLAGS, "aw", + [Define to the flags needed for the .section .eh_frame directive. ]) + fi -AC_CACHE_CHECK([for __attribute__((visibility("hidden")))], - libffi_cv_hidden_visibility_attribute, [ - echo 'int __attribute__ ((visibility ("hidden"))) foo (void) { return 1; }' > conftest.c - libffi_cv_hidden_visibility_attribute=no - if AC_TRY_COMMAND(${CC-cc} -Werror -S conftest.c -o conftest.s 1>&AS_MESSAGE_LOG_FD); then - if grep '\.hidden.*foo' conftest.s >/dev/null; then - libffi_cv_hidden_visibility_attribute=yes - fi - fi - rm -f conftest.* - ]) -if test $libffi_cv_hidden_visibility_attribute = yes; then - AC_DEFINE(HAVE_HIDDEN_VISIBILITY_ATTRIBUTE, 1, - [Define if __attribute__((visibility("hidden"))) is supported.]) + AC_CACHE_CHECK([for __attribute__((visibility("hidden")))], + libffi_cv_hidden_visibility_attribute, [ + echo 'int __attribute__ ((visibility ("hidden"))) foo (void) { return 1 ; }' > conftest.c + libffi_cv_hidden_visibility_attribute=no + if AC_TRY_COMMAND(${CC-cc} -Werror -S conftest.c -o conftest.s 1>&AS_MESSAGE_LOG_FD); then + if grep '\.hidden.*foo' conftest.s >/dev/null; then + libffi_cv_hidden_visibility_attribute=yes + fi + fi + rm -f conftest.* + ]) + if test $libffi_cv_hidden_visibility_attribute = yes; then + AC_DEFINE(HAVE_HIDDEN_VISIBILITY_ATTRIBUTE, 1, + [Define if __attribute__((visibility("hidden"))) is supported.]) + fi fi AH_BOTTOM([ @@ -400,6 +441,7 @@ AC_ARG_ENABLE(debug, if test "$enable_debug" = "yes"; then AC_DEFINE(FFI_DEBUG, 1, [Define this if you want extra debugging.]) fi) +AM_CONDITIONAL(FFI_DEBUG, test "$enable_debug" = "yes") AC_ARG_ENABLE(structs, [ --disable-structs omit code for struct support], diff --git a/libffi/generate-ios-source-and-headers.py b/libffi/generate-ios-source-and-headers.py new file mode 100644 index 0000000..c2bca73 --- /dev/null +++ b/libffi/generate-ios-source-and-headers.py @@ -0,0 +1,160 @@ +#!/usr/bin/env python + +import subprocess +import re +import os +import errno +import collections +import sys + +class Platform(object): + pass + +sdk_re = re.compile(r'.*-sdk ([a-zA-Z0-9.]*)') + +def sdkinfo(sdkname): + ret = {} + for line in subprocess.Popen(['xcodebuild', '-sdk', sdkname, '-version'], stdout=subprocess.PIPE).stdout: + kv = line.strip().split(': ', 1) + if len(kv) == 2: + k,v = kv + ret[k] = v + return ret + +sim_sdk_info = sdkinfo('iphonesimulator') +device_sdk_info = sdkinfo('iphoneos') + +def latest_sdks(): + latest_sim = None + latest_device = None + for line in subprocess.Popen(['xcodebuild', '-showsdks'], stdout=subprocess.PIPE).stdout: + match = sdk_re.match(line) + if match: + if 'Simulator' in line: + latest_sim = match.group(1) + elif 'iOS' in line: + latest_device = match.group(1) + + return latest_sim, latest_device + +sim_sdk, device_sdk = latest_sdks() + +class simulator_platform(Platform): + sdk='iphonesimulator' + arch = 'i386' + name = 'simulator' + triple = 'i386-apple-darwin10' + sdkroot = sim_sdk_info['Path'] + + prefix = "#if !defined(__arm__) && defined(__i386__)\n\n" + suffix = "\n\n#endif" + +class device_platform(Platform): + sdk='iphoneos' + name = 'ios' + arch = 'armv7' + triple = 'arm-apple-darwin10' + sdkroot = device_sdk_info['Path'] + + prefix = "#ifdef __arm__\n\n" + suffix = "\n\n#endif" + + +def move_file(src_dir, dst_dir, filename, file_suffix=None, prefix='', suffix=''): + if not os.path.exists(dst_dir): + os.makedirs(dst_dir) + + out_filename = filename + + if file_suffix: + split_name = os.path.splitext(filename) + out_filename = "%s_%s%s" % (split_name[0], file_suffix, split_name[1]) + + with open(os.path.join(src_dir, filename)) as in_file: + with open(os.path.join(dst_dir, out_filename), 'w') as out_file: + if prefix: + out_file.write(prefix) + + out_file.write(in_file.read()) + + if suffix: + out_file.write(suffix) + +headers_seen = collections.defaultdict(set) + +def move_source_tree(src_dir, dest_dir, dest_include_dir, arch=None, prefix=None, suffix=None): + for root, dirs, files in os.walk(src_dir, followlinks=True): + relroot = os.path.relpath(root,src_dir) + + def move_dir(arch, prefix='', suffix='', files=[]): + for file in files: + file_suffix = None + if file.endswith('.h'): + if dest_include_dir: + file_suffix = arch + if arch: + headers_seen[file].add(arch) + move_file(root, dest_include_dir, file, arch, prefix=prefix, suffix=suffix) + + elif dest_dir: + outroot = os.path.join(dest_dir, relroot) + move_file(root, outroot, file, prefix=prefix, suffix=suffix) + + if relroot == '.': + move_dir(arch=arch, + files=files, + prefix=prefix, + suffix=suffix) + elif relroot == 'arm': + move_dir(arch='arm', + prefix="#ifdef __arm__\n\n", + suffix="\n\n#endif", + files=files) + elif relroot == 'x86': + move_dir(arch='i386', + prefix="#if !defined(__arm__) && defined(__i386__)\n\n", + suffix="\n\n#endif", + files=files) + +def build_target(platform): + def xcrun_cmd(cmd): + return subprocess.check_output(['xcrun', '-sdk', platform.sdkroot, '-find', cmd]).strip() + + build_dir = 'build_' + platform.name + if not os.path.exists(build_dir): + os.makedirs(build_dir) + env = dict(CC=xcrun_cmd('clang'), + LD=xcrun_cmd('ld'), + CFLAGS='-arch %s -isysroot %s -miphoneos-version-min=4.0' % (platform.arch, platform.sdkroot)) + working_dir=os.getcwd() + try: + os.chdir(build_dir) + subprocess.check_call(['../configure', '-host', platform.triple], env=env) + move_source_tree('.', None, '../ios/include', + arch=platform.arch, + prefix=platform.prefix, + suffix=platform.suffix) + move_source_tree('./include', None, '../ios/include', + arch=platform.arch, + prefix=platform.prefix, + suffix=platform.suffix) + finally: + os.chdir(working_dir) + + for header_name, archs in headers_seen.iteritems(): + basename, suffix = os.path.splitext(header_name) + +def main(): + move_source_tree('src', 'ios/src', 'ios/include') + move_source_tree('include', None, 'ios/include') + build_target(simulator_platform) + build_target(device_platform) + + for header_name, archs in headers_seen.iteritems(): + basename, suffix = os.path.splitext(header_name) + with open(os.path.join('ios/include', header_name), 'w') as header: + for arch in archs: + header.write('#include <%s_%s%s>\n' % (basename, arch, suffix)) + +if __name__ == '__main__': + main() diff --git a/libffi/generate-osx-source-and-headers.py b/libffi/generate-osx-source-and-headers.py new file mode 100644 index 0000000..64313c1 --- /dev/null +++ b/libffi/generate-osx-source-and-headers.py @@ -0,0 +1,153 @@ +#!/usr/bin/env python +import subprocess +import re +import os +import errno +import collections +import sys + +class Platform(object): + pass + +sdk_re = re.compile(r'.*-sdk ([a-zA-Z0-9.]*)') + +def sdkinfo(sdkname): + ret = {} + for line in subprocess.Popen(['xcodebuild', '-sdk', sdkname, '-version'], stdout=subprocess.PIPE).stdout: + kv = line.strip().split(': ', 1) + if len(kv) == 2: + k,v = kv + ret[k] = v + return ret + +desktop_sdk_info = sdkinfo('macosx') + +def latest_sdks(): + latest_desktop = None + for line in subprocess.Popen(['xcodebuild', '-showsdks'], stdout=subprocess.PIPE).stdout: + match = sdk_re.match(line) + if match: + if 'OS X' in line: + latest_desktop = match.group(1) + + return latest_desktop + +desktop_sdk = latest_sdks() + +class desktop_platform_32(Platform): + sdk='macosx' + arch = 'i386' + name = 'mac32' + triple = 'i386-apple-darwin10' + sdkroot = desktop_sdk_info['Path'] + + prefix = "#if defined(__i386__) && !defined(__x86_64__)\n\n" + suffix = "\n\n#endif" + +class desktop_platform_64(Platform): + sdk='macosx' + arch = 'x86_64' + name = 'mac' + triple = 'x86_64-apple-darwin10' + sdkroot = desktop_sdk_info['Path'] + + prefix = "#if !defined(__i386__) && defined(__x86_64__)\n\n" + suffix = "\n\n#endif" + +def move_file(src_dir, dst_dir, filename, file_suffix=None, prefix='', suffix=''): + if not os.path.exists(dst_dir): + os.makedirs(dst_dir) + + out_filename = filename + + if file_suffix: + split_name = os.path.splitext(filename) + out_filename = "%s_%s%s" % (split_name[0], file_suffix, split_name[1]) + + with open(os.path.join(src_dir, filename)) as in_file: + with open(os.path.join(dst_dir, out_filename), 'w') as out_file: + if prefix: + out_file.write(prefix) + + out_file.write(in_file.read()) + + if suffix: + out_file.write(suffix) + +headers_seen = collections.defaultdict(set) + +def move_source_tree(src_dir, dest_dir, dest_include_dir, arch=None, prefix=None, suffix=None): + for root, dirs, files in os.walk(src_dir, followlinks=True): + relroot = os.path.relpath(root,src_dir) + + def move_dir(arch, prefix='', suffix='', files=[]): + for file in files: + file_suffix = None + if file.endswith('.h'): + if dest_include_dir: + file_suffix = arch + if arch: + headers_seen[file].add(arch) + move_file(root, dest_include_dir, file, arch, prefix=prefix, suffix=suffix) + + elif dest_dir: + outroot = os.path.join(dest_dir, relroot) + move_file(root, outroot, file, prefix=prefix, suffix=suffix) + + if relroot == '.': + move_dir(arch=arch, + files=files, + prefix=prefix, + suffix=suffix) + elif relroot == 'x86': + move_dir(arch='i386', + prefix="#if defined(__i386__) && !defined(__x86_64__)\n\n", + suffix="\n\n#endif", + files=files) + move_dir(arch='x86_64', + prefix="#if !defined(__i386__) && defined(__x86_64__)\n\n", + suffix="\n\n#endif", + files=files) + +def build_target(platform): + def xcrun_cmd(cmd): + return subprocess.check_output(['xcrun', '-sdk', platform.sdkroot, '-find', cmd]).strip() + + build_dir = 'build_' + platform.name + if not os.path.exists(build_dir): + os.makedirs(build_dir) + env = dict(CC=xcrun_cmd('clang'), + LD=xcrun_cmd('ld'), + CFLAGS='-arch %s -isysroot %s -mmacosx-version-min=10.6' % (platform.arch, platform.sdkroot)) + working_dir=os.getcwd() + try: + os.chdir(build_dir) + subprocess.check_call(['../configure', '-host', platform.triple], env=env) + move_source_tree('.', None, '../osx/include', + arch=platform.arch, + prefix=platform.prefix, + suffix=platform.suffix) + move_source_tree('./include', None, '../osx/include', + arch=platform.arch, + prefix=platform.prefix, + suffix=platform.suffix) + finally: + os.chdir(working_dir) + + for header_name, archs in headers_seen.iteritems(): + basename, suffix = os.path.splitext(header_name) + +def main(): + move_source_tree('src', 'osx/src', 'osx/include') + move_source_tree('include', None, 'osx/include') + build_target(desktop_platform_32) + build_target(desktop_platform_64) + + for header_name, archs in headers_seen.iteritems(): + basename, suffix = os.path.splitext(header_name) + with open(os.path.join('osx/include', header_name), 'w') as header: + for arch in archs: + header.write('#include <%s_%s%s>\n' % (basename, arch, suffix)) + +if __name__ == '__main__': + main() diff --git a/libffi/libffi.xcodeproj/project.pbxproj b/libffi/libffi.xcodeproj/project.pbxproj new file mode 100644 index 0000000..14c39a2 --- /dev/null +++ b/libffi/libffi.xcodeproj/project.pbxproj @@ -0,0 +1,579 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 6C43CBDC1534F76F00162364 /* ffi.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CBBD1534F76F00162364 /* ffi.c */; }; + 6C43CBDD1534F76F00162364 /* sysv.S in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CBBF1534F76F00162364 /* sysv.S */; }; + 6C43CBDE1534F76F00162364 /* trampoline.S in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CBC01534F76F00162364 /* trampoline.S */; }; + 6C43CBE61534F76F00162364 /* darwin.S in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CBC91534F76F00162364 /* darwin.S */; }; + 6C43CBE81534F76F00162364 /* ffi.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CBCB1534F76F00162364 /* ffi.c */; }; + 6C43CC1F1534F77800162364 /* darwin.S in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC051534F77800162364 /* darwin.S */; }; + 6C43CC201534F77800162364 /* darwin64.S in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC061534F77800162364 /* darwin64.S */; }; + 6C43CC211534F77800162364 /* ffi.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC071534F77800162364 /* ffi.c */; }; + 6C43CC221534F77800162364 /* ffi64.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC081534F77800162364 /* ffi64.c */; }; + 6C43CC2F1534F7BE00162364 /* closures.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC281534F7BE00162364 /* closures.c */; }; + 6C43CC301534F7BE00162364 /* closures.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC281534F7BE00162364 /* closures.c */; }; + 6C43CC351534F7BE00162364 /* java_raw_api.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC2B1534F7BE00162364 /* java_raw_api.c */; }; + 6C43CC361534F7BE00162364 /* java_raw_api.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC2B1534F7BE00162364 /* java_raw_api.c */; }; + 6C43CC371534F7BE00162364 /* prep_cif.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC2C1534F7BE00162364 /* prep_cif.c */; }; + 6C43CC381534F7BE00162364 /* prep_cif.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC2C1534F7BE00162364 /* prep_cif.c */; }; + 6C43CC391534F7BE00162364 /* raw_api.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC2D1534F7BE00162364 /* raw_api.c */; }; + 6C43CC3A1534F7BE00162364 /* raw_api.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC2D1534F7BE00162364 /* raw_api.c */; }; + 6C43CC3B1534F7BE00162364 /* types.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC2E1534F7BE00162364 /* types.c */; }; + 6C43CC3C1534F7BE00162364 /* types.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC2E1534F7BE00162364 /* types.c */; }; + 6C43CC971535032600162364 /* ffi.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CC8D1535032600162364 /* ffi.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6C43CC981535032600162364 /* ffi_common.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CC8E1535032600162364 /* ffi_common.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6C43CC991535032600162364 /* ffi_i386.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CC8F1535032600162364 /* ffi_i386.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6C43CC9A1535032600162364 /* ffi_x86_64.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CC901535032600162364 /* ffi_x86_64.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6C43CC9B1535032600162364 /* fficonfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CC911535032600162364 /* fficonfig.h */; }; + 6C43CC9C1535032600162364 /* fficonfig_i386.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CC921535032600162364 /* fficonfig_i386.h */; }; + 6C43CC9D1535032600162364 /* fficonfig_x86_64.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CC931535032600162364 /* fficonfig_x86_64.h */; }; + 6C43CC9E1535032600162364 /* ffitarget.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CC941535032600162364 /* ffitarget.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6C43CC9F1535032600162364 /* ffitarget_i386.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CC951535032600162364 /* ffitarget_i386.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6C43CCA01535032600162364 /* ffitarget_x86_64.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CC961535032600162364 /* ffitarget_x86_64.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6C43CCAD1535039600162364 /* ffi.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCA21535039600162364 /* ffi.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6C43CCAE1535039600162364 /* ffi_armv7.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCA31535039600162364 /* ffi_armv7.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6C43CCAF1535039600162364 /* ffi_common.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCA41535039600162364 /* ffi_common.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6C43CCB01535039600162364 /* ffi_i386.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCA51535039600162364 /* ffi_i386.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6C43CCB11535039600162364 /* fficonfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCA61535039600162364 /* fficonfig.h */; }; + 6C43CCB21535039600162364 /* fficonfig_armv7.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCA71535039600162364 /* fficonfig_armv7.h */; }; + 6C43CCB31535039600162364 /* fficonfig_i386.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCA81535039600162364 /* fficonfig_i386.h */; }; + 6C43CCB41535039600162364 /* ffitarget.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCA91535039600162364 /* ffitarget.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6C43CCB51535039600162364 /* ffitarget_arm.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCAA1535039600162364 /* ffitarget_arm.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6C43CCB61535039600162364 /* ffitarget_armv7.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCAB1535039600162364 /* ffitarget_armv7.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6C43CCB71535039600162364 /* ffitarget_i386.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCAC1535039600162364 /* ffitarget_i386.h */; settings = {ATTRIBUTES = (Public, ); }; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 6C43CB3D1534E9D100162364 /* libffi.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libffi.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 6C43CBBD1534F76F00162364 /* ffi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi.c; sourceTree = ""; }; + 6C43CBBF1534F76F00162364 /* sysv.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = sysv.S; sourceTree = ""; }; + 6C43CBC01534F76F00162364 /* trampoline.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = trampoline.S; sourceTree = ""; }; + 6C43CBC91534F76F00162364 /* darwin.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = darwin.S; sourceTree = ""; }; + 6C43CBCB1534F76F00162364 /* ffi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi.c; sourceTree = ""; }; + 6C43CC051534F77800162364 /* darwin.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = darwin.S; sourceTree = ""; }; + 6C43CC061534F77800162364 /* darwin64.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = darwin64.S; sourceTree = ""; }; + 6C43CC071534F77800162364 /* ffi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi.c; sourceTree = ""; }; + 6C43CC081534F77800162364 /* ffi64.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi64.c; sourceTree = ""; }; + 6C43CC281534F7BE00162364 /* closures.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = closures.c; path = src/closures.c; sourceTree = SOURCE_ROOT; }; + 6C43CC2B1534F7BE00162364 /* java_raw_api.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = java_raw_api.c; path = src/java_raw_api.c; sourceTree = SOURCE_ROOT; }; + 6C43CC2C1534F7BE00162364 /* prep_cif.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = prep_cif.c; path = src/prep_cif.c; sourceTree = SOURCE_ROOT; }; + 6C43CC2D1534F7BE00162364 /* raw_api.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = raw_api.c; path = src/raw_api.c; sourceTree = SOURCE_ROOT; }; + 6C43CC2E1534F7BE00162364 /* types.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = types.c; path = src/types.c; sourceTree = SOURCE_ROOT; }; + 6C43CC8D1535032600162364 /* ffi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi.h; sourceTree = ""; }; + 6C43CC8E1535032600162364 /* ffi_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_common.h; sourceTree = ""; }; + 6C43CC8F1535032600162364 /* ffi_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_i386.h; sourceTree = ""; }; + 6C43CC901535032600162364 /* ffi_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_x86_64.h; sourceTree = ""; }; + 6C43CC911535032600162364 /* fficonfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig.h; sourceTree = ""; }; + 6C43CC921535032600162364 /* fficonfig_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig_i386.h; sourceTree = ""; }; + 6C43CC931535032600162364 /* fficonfig_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig_x86_64.h; sourceTree = ""; }; + 6C43CC941535032600162364 /* ffitarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget.h; sourceTree = ""; }; + 6C43CC951535032600162364 /* ffitarget_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_i386.h; sourceTree = ""; }; + 6C43CC961535032600162364 /* ffitarget_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_x86_64.h; sourceTree = ""; }; + 6C43CCA21535039600162364 /* ffi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi.h; sourceTree = ""; }; + 6C43CCA31535039600162364 /* ffi_armv7.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_armv7.h; sourceTree = ""; }; + 6C43CCA41535039600162364 /* ffi_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_common.h; sourceTree = ""; }; + 6C43CCA51535039600162364 /* ffi_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_i386.h; sourceTree = ""; }; + 6C43CCA61535039600162364 /* fficonfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig.h; sourceTree = ""; }; + 6C43CCA71535039600162364 /* fficonfig_armv7.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig_armv7.h; sourceTree = ""; }; + 6C43CCA81535039600162364 /* fficonfig_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig_i386.h; sourceTree = ""; }; + 6C43CCA91535039600162364 /* ffitarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget.h; sourceTree = ""; }; + 6C43CCAA1535039600162364 /* ffitarget_arm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_arm.h; sourceTree = ""; }; + 6C43CCAB1535039600162364 /* ffitarget_armv7.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_armv7.h; sourceTree = ""; }; + 6C43CCAC1535039600162364 /* ffitarget_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_i386.h; sourceTree = ""; }; + F6F980BA147386130008F121 /* libffi.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libffi.a; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 6C43CB3A1534E9D100162364 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F6F980B7147386130008F121 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 6C43CBAF1534F76F00162364 /* iOS */ = { + isa = PBXGroup; + children = ( + 6C43CCA11535039600162364 /* include */, + 6C43CBBB1534F76F00162364 /* src */, + ); + name = iOS; + path = ios; + sourceTree = ""; + }; + 6C43CBBB1534F76F00162364 /* src */ = { + isa = PBXGroup; + children = ( + 6C43CBC81534F76F00162364 /* x86 */, + 6C43CBBC1534F76F00162364 /* arm */, + ); + path = src; + sourceTree = ""; + }; + 6C43CBBC1534F76F00162364 /* arm */ = { + isa = PBXGroup; + children = ( + 6C43CBBD1534F76F00162364 /* ffi.c */, + 6C43CBBF1534F76F00162364 /* sysv.S */, + 6C43CBC01534F76F00162364 /* trampoline.S */, + ); + path = arm; + sourceTree = ""; + }; + 6C43CBC81534F76F00162364 /* x86 */ = { + isa = PBXGroup; + children = ( + 6C43CBC91534F76F00162364 /* darwin.S */, + 6C43CBCB1534F76F00162364 /* ffi.c */, + ); + path = x86; + sourceTree = ""; + }; + 6C43CBF01534F77800162364 /* OS X */ = { + isa = PBXGroup; + children = ( + 6C43CC8C1535032600162364 /* include */, + 6C43CBFC1534F77800162364 /* src */, + ); + name = "OS X"; + path = osx; + sourceTree = ""; + }; + 6C43CBFC1534F77800162364 /* src */ = { + isa = PBXGroup; + children = ( + 6C43CC041534F77800162364 /* x86 */, + ); + path = src; + sourceTree = ""; + }; + 6C43CC041534F77800162364 /* x86 */ = { + isa = PBXGroup; + children = ( + 6C43CC051534F77800162364 /* darwin.S */, + 6C43CC061534F77800162364 /* darwin64.S */, + 6C43CC071534F77800162364 /* ffi.c */, + 6C43CC081534F77800162364 /* ffi64.c */, + ); + path = x86; + sourceTree = ""; + }; + 6C43CC3D1534F7C400162364 /* src */ = { + isa = PBXGroup; + children = ( + 6C43CC281534F7BE00162364 /* closures.c */, + 6C43CC2B1534F7BE00162364 /* java_raw_api.c */, + 6C43CC2C1534F7BE00162364 /* prep_cif.c */, + 6C43CC2D1534F7BE00162364 /* raw_api.c */, + 6C43CC2E1534F7BE00162364 /* types.c */, + ); + name = src; + path = ios; + sourceTree = ""; + }; + 6C43CC8C1535032600162364 /* include */ = { + isa = PBXGroup; + children = ( + 6C43CC8D1535032600162364 /* ffi.h */, + 6C43CC8E1535032600162364 /* ffi_common.h */, + 6C43CC8F1535032600162364 /* ffi_i386.h */, + 6C43CC901535032600162364 /* ffi_x86_64.h */, + 6C43CC911535032600162364 /* fficonfig.h */, + 6C43CC921535032600162364 /* fficonfig_i386.h */, + 6C43CC931535032600162364 /* fficonfig_x86_64.h */, + 6C43CC941535032600162364 /* ffitarget.h */, + 6C43CC951535032600162364 /* ffitarget_i386.h */, + 6C43CC961535032600162364 /* ffitarget_x86_64.h */, + ); + path = include; + sourceTree = ""; + }; + 6C43CCA11535039600162364 /* include */ = { + isa = PBXGroup; + children = ( + 6C43CCA21535039600162364 /* ffi.h */, + 6C43CCA31535039600162364 /* ffi_armv7.h */, + 6C43CCA41535039600162364 /* ffi_common.h */, + 6C43CCA51535039600162364 /* ffi_i386.h */, + 6C43CCA61535039600162364 /* fficonfig.h */, + 6C43CCA71535039600162364 /* fficonfig_armv7.h */, + 6C43CCA81535039600162364 /* fficonfig_i386.h */, + 6C43CCA91535039600162364 /* ffitarget.h */, + 6C43CCAA1535039600162364 /* ffitarget_arm.h */, + 6C43CCAB1535039600162364 /* ffitarget_armv7.h */, + 6C43CCAC1535039600162364 /* ffitarget_i386.h */, + ); + path = include; + sourceTree = ""; + }; + F6B0839514721EE50031D8A1 = { + isa = PBXGroup; + children = ( + 6C43CC3D1534F7C400162364 /* src */, + 6C43CBAF1534F76F00162364 /* iOS */, + 6C43CBF01534F77800162364 /* OS X */, + F6F980C6147386260008F121 /* Products */, + ); + sourceTree = ""; + }; + F6F980C6147386260008F121 /* Products */ = { + isa = PBXGroup; + children = ( + F6F980BA147386130008F121 /* libffi.a */, + 6C43CB3D1534E9D100162364 /* libffi.a */, + ); + name = Products; + path = ../..; + sourceTree = BUILT_PRODUCTS_DIR; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 6C43CB3B1534E9D100162364 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 6C43CC971535032600162364 /* ffi.h in Headers */, + 6C43CC981535032600162364 /* ffi_common.h in Headers */, + 6C43CC991535032600162364 /* ffi_i386.h in Headers */, + 6C43CC9A1535032600162364 /* ffi_x86_64.h in Headers */, + 6C43CC9E1535032600162364 /* ffitarget.h in Headers */, + 6C43CC9F1535032600162364 /* ffitarget_i386.h in Headers */, + 6C43CCA01535032600162364 /* ffitarget_x86_64.h in Headers */, + 6C43CC9B1535032600162364 /* fficonfig.h in Headers */, + 6C43CC9C1535032600162364 /* fficonfig_i386.h in Headers */, + 6C43CC9D1535032600162364 /* fficonfig_x86_64.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F6F980B8147386130008F121 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 6C43CCAD1535039600162364 /* ffi.h in Headers */, + 6C43CCAE1535039600162364 /* ffi_armv7.h in Headers */, + 6C43CCAF1535039600162364 /* ffi_common.h in Headers */, + 6C43CCB01535039600162364 /* ffi_i386.h in Headers */, + 6C43CCB41535039600162364 /* ffitarget.h in Headers */, + 6C43CCB51535039600162364 /* ffitarget_arm.h in Headers */, + 6C43CCB61535039600162364 /* ffitarget_armv7.h in Headers */, + 6C43CCB71535039600162364 /* ffitarget_i386.h in Headers */, + 6C43CCB11535039600162364 /* fficonfig.h in Headers */, + 6C43CCB21535039600162364 /* fficonfig_armv7.h in Headers */, + 6C43CCB31535039600162364 /* fficonfig_i386.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 6C43CB3C1534E9D100162364 /* libffi OS X */ = { + isa = PBXNativeTarget; + buildConfigurationList = 6C43CB4A1534E9D100162364 /* Build configuration list for PBXNativeTarget "libffi OS X" */; + buildPhases = ( + 6C43CC401534FF3B00162364 /* Generate Source and Headers */, + 6C43CB391534E9D100162364 /* Sources */, + 6C43CB3A1534E9D100162364 /* Frameworks */, + 6C43CB3B1534E9D100162364 /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "libffi OS X"; + productName = "ffi OS X"; + productReference = 6C43CB3D1534E9D100162364 /* libffi.a */; + productType = "com.apple.product-type.library.static"; + }; + F6F980B9147386130008F121 /* libffi iOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = F6F980C4147386130008F121 /* Build configuration list for PBXNativeTarget "libffi iOS" */; + buildPhases = ( + 6C43CC3E1534F8E200162364 /* Generate Trampoline */, + 6C43CC3F1534FF1B00162364 /* Generate Source and Headers */, + F6F980B6147386130008F121 /* Sources */, + F6F980B7147386130008F121 /* Frameworks */, + F6F980B8147386130008F121 /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "libffi iOS"; + productName = ffi; + productReference = F6F980BA147386130008F121 /* libffi.a */; + productType = "com.apple.product-type.library.static"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + F6B0839714721EE50031D8A1 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0430; + }; + buildConfigurationList = F6B0839A14721EE50031D8A1 /* Build configuration list for PBXProject "libffi" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = F6B0839514721EE50031D8A1; + productRefGroup = F6B0839514721EE50031D8A1; + projectDirPath = ""; + projectRoot = ""; + targets = ( + F6F980B9147386130008F121 /* libffi iOS */, + 6C43CB3C1534E9D100162364 /* libffi OS X */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXShellScriptBuildPhase section */ + 6C43CC3E1534F8E200162364 /* Generate Trampoline */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Generate Trampoline"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /usr/bin/python; + shellScript = "import subprocess\nimport re\nimport os\nimport errno\nimport sys\n\ndef main():\n with open('src/arm/trampoline.S', 'w') as tramp_out:\n p = subprocess.Popen(['bash', 'src/arm/gentramp.sh'], stdout=tramp_out)\n p.wait()\n\nif __name__ == '__main__':\n main()"; + }; + 6C43CC3F1534FF1B00162364 /* Generate Source and Headers */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Generate Source and Headers"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/usr/bin/python generate-ios-source-and-headers.py"; + }; + 6C43CC401534FF3B00162364 /* Generate Source and Headers */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Generate Source and Headers"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/usr/bin/python generate-osx-source-and-headers.py"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 6C43CB391534E9D100162364 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6C43CC1F1534F77800162364 /* darwin.S in Sources */, + 6C43CC201534F77800162364 /* darwin64.S in Sources */, + 6C43CC211534F77800162364 /* ffi.c in Sources */, + 6C43CC221534F77800162364 /* ffi64.c in Sources */, + 6C43CC301534F7BE00162364 /* closures.c in Sources */, + 6C43CC361534F7BE00162364 /* java_raw_api.c in Sources */, + 6C43CC381534F7BE00162364 /* prep_cif.c in Sources */, + 6C43CC3A1534F7BE00162364 /* raw_api.c in Sources */, + 6C43CC3C1534F7BE00162364 /* types.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F6F980B6147386130008F121 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6C43CBDC1534F76F00162364 /* ffi.c in Sources */, + 6C43CBDD1534F76F00162364 /* sysv.S in Sources */, + 6C43CBDE1534F76F00162364 /* trampoline.S in Sources */, + 6C43CBE61534F76F00162364 /* darwin.S in Sources */, + 6C43CBE81534F76F00162364 /* ffi.c in Sources */, + 6C43CC2F1534F7BE00162364 /* closures.c in Sources */, + 6C43CC351534F7BE00162364 /* java_raw_api.c in Sources */, + 6C43CC371534F7BE00162364 /* prep_cif.c in Sources */, + 6C43CC391534F7BE00162364 /* raw_api.c in Sources */, + 6C43CC3B1534F7BE00162364 /* types.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 6C43CB4B1534E9D100162364 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; + DSTROOT = /tmp/ffi.dst; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SYSTEM_APPS_DIR)/Xcode.app/Contents/Developer/Library/Frameworks\"", + ); + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + MACOSX_DEPLOYMENT_TARGET = 10.6; + ONLY_ACTIVE_ARCH = YES; + PRODUCT_NAME = ffi; + SDKROOT = macosx; + }; + name = Debug; + }; + 6C43CB4C1534E9D100162364 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DSTROOT = /tmp/ffi.dst; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SYSTEM_APPS_DIR)/Xcode.app/Contents/Developer/Library/Frameworks\"", + ); + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + MACOSX_DEPLOYMENT_TARGET = 10.6; + PRODUCT_NAME = ffi; + SDKROOT = macosx; + }; + name = Release; + }; + F6B083AB14721EE50031D8A1 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + COPY_PHASE_STRIP = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VALUE = NO; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = ios/include; + SDKROOT = iphoneos; + }; + name = Debug; + }; + F6B083AC14721EE50031D8A1 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + COPY_PHASE_STRIP = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_PREPROCESSOR_DEFINITIONS = ""; + GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VALUE = NO; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = ios/include; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + F6F980C2147386130008F121 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + armv6, + armv7, + ); + DSTROOT = /tmp/ffi.dst; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_THUMB_SUPPORT = NO; + IPHONEOS_DEPLOYMENT_TARGET = 4.0; + OTHER_LDFLAGS = "-ObjC"; + PRODUCT_NAME = ffi; + SKIP_INSTALL = YES; + }; + name = Debug; + }; + F6F980C3147386130008F121 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + armv6, + armv7, + ); + DSTROOT = /tmp/ffi.dst; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_THUMB_SUPPORT = NO; + IPHONEOS_DEPLOYMENT_TARGET = 4.0; + OTHER_LDFLAGS = "-ObjC"; + PRODUCT_NAME = ffi; + SKIP_INSTALL = YES; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 6C43CB4A1534E9D100162364 /* Build configuration list for PBXNativeTarget "libffi OS X" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6C43CB4B1534E9D100162364 /* Debug */, + 6C43CB4C1534E9D100162364 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + F6B0839A14721EE50031D8A1 /* Build configuration list for PBXProject "libffi" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F6B083AB14721EE50031D8A1 /* Debug */, + F6B083AC14721EE50031D8A1 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + F6F980C4147386130008F121 /* Build configuration list for PBXNativeTarget "libffi iOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F6F980C2147386130008F121 /* Debug */, + F6F980C3147386130008F121 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = F6B0839714721EE50031D8A1 /* Project object */; +} diff --git a/libffi/man/Makefile.am b/libffi/man/Makefile.am index 2519277..afcbfb6 100644 --- a/libffi/man/Makefile.am +++ b/libffi/man/Makefile.am @@ -2,7 +2,7 @@ AUTOMAKE_OPTIONS=foreign -EXTRA_DIST = ffi.3 ffi_call.3 ffi_prep_cif.3 +EXTRA_DIST = ffi.3 ffi_call.3 ffi_prep_cif.3 ffi_prep_cif_var.3 -man_MANS = ffi.3 ffi_call.3 ffi_prep_cif.3 +man_MANS = ffi.3 ffi_call.3 ffi_prep_cif.3 ffi_prep_cif_var.3 diff --git a/libffi/man/Makefile.in b/libffi/man/Makefile.in index 79466b3..199fea6 100644 --- a/libffi/man/Makefile.in +++ b/libffi/man/Makefile.in @@ -1,9 +1,9 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. +# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -15,6 +15,23 @@ @SET_MAKE@ VPATH = @srcdir@ +am__make_dryrun = \ + { \ + am__dry=no; \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ + | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ + *) \ + for am__flg in $$MAKEFLAGS; do \ + case $$am__flg in \ + *=*|--*) ;; \ + *n*) am__dry=yes; break;; \ + esac; \ + done;; \ + esac; \ + test $$am__dry = yes; \ + } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -37,22 +54,32 @@ target_triplet = @target@ subdir = man DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/../config/depstand.m4 \ - $(top_srcdir)/../config/lead-dot.m4 \ - $(top_srcdir)/../config/multi.m4 \ - $(top_srcdir)/../config/override.m4 \ - $(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \ - $(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \ - $(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/acinclude.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/asmcfi.m4 \ + $(top_srcdir)/m4/ax_cc_maxopt.m4 \ + $(top_srcdir)/m4/ax_cflags_warn_all.m4 \ + $(top_srcdir)/m4/ax_check_compile_flag.m4 \ + $(top_srcdir)/m4/ax_compiler_vendor.m4 \ + $(top_srcdir)/m4/ax_configure_args.m4 \ + $(top_srcdir)/m4/ax_enable_builddir.m4 \ + $(top_srcdir)/m4/ax_gcc_archflag.m4 \ + $(top_srcdir)/m4/ax_gcc_x86_cpuid.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) -mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs +mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/fficonfig.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = SOURCES = DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ @@ -74,6 +101,12 @@ am__nobase_list = $(am__nobase_strip_setup); \ am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } man3dir = $(mandir)/man3 am__installdirs = "$(DESTDIR)$(man3dir)" NROFF = nroff @@ -100,6 +133,7 @@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ @@ -107,6 +141,7 @@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ +FFI_EXEC_TRAMPOLINE_TABLE = @FFI_EXEC_TRAMPOLINE_TABLE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_LONG_DOUBLE = @HAVE_LONG_DOUBLE@ @@ -125,6 +160,7 @@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ @@ -140,6 +176,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PRTDIAG = @PRTDIAG@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ @@ -152,6 +189,7 @@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ @@ -159,6 +197,7 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +ax_enable_builddir_sed = @ax_enable_builddir_sed@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -186,7 +225,6 @@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ -multi_basedir = @multi_basedir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ @@ -195,6 +233,7 @@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ +sys_symbol_underscore = @sys_symbol_underscore@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ @@ -207,8 +246,8 @@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = foreign -EXTRA_DIST = ffi.3 ffi_call.3 ffi_prep_cif.3 -man_MANS = ffi.3 ffi_call.3 ffi_prep_cif.3 +EXTRA_DIST = ffi.3 ffi_call.3 ffi_prep_cif.3 ffi_prep_cif_var.3 +man_MANS = ffi.3 ffi_call.3 ffi_prep_cif.3 ffi_prep_cif_var.3 all: all-am .SUFFIXES: @@ -250,11 +289,18 @@ clean-libtool: -rm -rf .libs _libs install-man3: $(man_MANS) @$(NORMAL_INSTALL) - test -z "$(man3dir)" || $(MKDIR_P) "$(DESTDIR)$(man3dir)" - @list=''; test -n "$(man3dir)" || exit 0; \ - { for i in $$list; do echo "$$i"; done; \ - l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ - sed -n '/\.3[a-z]*$$/p'; \ + @list1=''; \ + list2='$(man_MANS)'; \ + test -n "$(man3dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man3dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man3dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.3[a-z]*$$/p'; \ + fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ @@ -283,9 +329,7 @@ uninstall-man3: sed -n '/\.3[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ - test -z "$$files" || { \ - echo " ( cd '$(DESTDIR)$(man3dir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(man3dir)" && rm -f $$files; } + dir='$(DESTDIR)$(man3dir)'; $(am__uninstall_files_from_dir) tags: TAGS TAGS: @@ -353,10 +397,15 @@ install-am: all-am installcheck: installcheck-am install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi mostlyclean-generic: clean-generic: diff --git a/libffi/src/aarch64/ffi.c b/libffi/src/aarch64/ffi.c new file mode 100644 index 0000000..1405665 --- /dev/null +++ b/libffi/src/aarch64/ffi.c @@ -0,0 +1,1076 @@ +/* Copyright (c) 2009, 2010, 2011, 2012 ARM Ltd. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +``Software''), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include + +#include +#include + +#include + +/* Stack alignment requirement in bytes */ +#define AARCH64_STACK_ALIGN 16 + +#define N_X_ARG_REG 8 +#define N_V_ARG_REG 8 + +#define AARCH64_FFI_WITH_V (1 << AARCH64_FFI_WITH_V_BIT) + +union _d +{ + UINT64 d; + UINT32 s[2]; +}; + +struct call_context +{ + UINT64 x [AARCH64_N_XREG]; + struct + { + union _d d[2]; + } v [AARCH64_N_VREG]; +}; + +static void * +get_x_addr (struct call_context *context, unsigned n) +{ + return &context->x[n]; +} + +static void * +get_s_addr (struct call_context *context, unsigned n) +{ +#if defined __AARCH64EB__ + return &context->v[n].d[1].s[1]; +#else + return &context->v[n].d[0].s[0]; +#endif +} + +static void * +get_d_addr (struct call_context *context, unsigned n) +{ +#if defined __AARCH64EB__ + return &context->v[n].d[1]; +#else + return &context->v[n].d[0]; +#endif +} + +static void * +get_v_addr (struct call_context *context, unsigned n) +{ + return &context->v[n]; +} + +/* Return the memory location at which a basic type would reside + were it to have been stored in register n. */ + +static void * +get_basic_type_addr (unsigned short type, struct call_context *context, + unsigned n) +{ + switch (type) + { + case FFI_TYPE_FLOAT: + return get_s_addr (context, n); + case FFI_TYPE_DOUBLE: + return get_d_addr (context, n); + case FFI_TYPE_LONGDOUBLE: + return get_v_addr (context, n); + case FFI_TYPE_UINT8: + case FFI_TYPE_SINT8: + case FFI_TYPE_UINT16: + case FFI_TYPE_SINT16: + case FFI_TYPE_UINT32: + case FFI_TYPE_SINT32: + case FFI_TYPE_INT: + case FFI_TYPE_POINTER: + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + return get_x_addr (context, n); + default: + FFI_ASSERT (0); + return NULL; + } +} + +/* Return the alignment width for each of the basic types. */ + +static size_t +get_basic_type_alignment (unsigned short type) +{ + switch (type) + { + case FFI_TYPE_FLOAT: + case FFI_TYPE_DOUBLE: + return sizeof (UINT64); + case FFI_TYPE_LONGDOUBLE: + return sizeof (long double); + case FFI_TYPE_UINT8: + case FFI_TYPE_SINT8: + case FFI_TYPE_UINT16: + case FFI_TYPE_SINT16: + case FFI_TYPE_UINT32: + case FFI_TYPE_INT: + case FFI_TYPE_SINT32: + case FFI_TYPE_POINTER: + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + return sizeof (UINT64); + + default: + FFI_ASSERT (0); + return 0; + } +} + +/* Return the size in bytes for each of the basic types. */ + +static size_t +get_basic_type_size (unsigned short type) +{ + switch (type) + { + case FFI_TYPE_FLOAT: + return sizeof (UINT32); + case FFI_TYPE_DOUBLE: + return sizeof (UINT64); + case FFI_TYPE_LONGDOUBLE: + return sizeof (long double); + case FFI_TYPE_UINT8: + return sizeof (UINT8); + case FFI_TYPE_SINT8: + return sizeof (SINT8); + case FFI_TYPE_UINT16: + return sizeof (UINT16); + case FFI_TYPE_SINT16: + return sizeof (SINT16); + case FFI_TYPE_UINT32: + return sizeof (UINT32); + case FFI_TYPE_INT: + case FFI_TYPE_SINT32: + return sizeof (SINT32); + case FFI_TYPE_POINTER: + case FFI_TYPE_UINT64: + return sizeof (UINT64); + case FFI_TYPE_SINT64: + return sizeof (SINT64); + + default: + FFI_ASSERT (0); + return 0; + } +} + +extern void +ffi_call_SYSV (unsigned (*)(struct call_context *context, unsigned char *, + extended_cif *), + struct call_context *context, + extended_cif *, + unsigned, + void (*fn)(void)); + +extern void +ffi_closure_SYSV (ffi_closure *); + +/* Test for an FFI floating point representation. */ + +static unsigned +is_floating_type (unsigned short type) +{ + return (type == FFI_TYPE_FLOAT || type == FFI_TYPE_DOUBLE + || type == FFI_TYPE_LONGDOUBLE); +} + +/* Test for a homogeneous structure. */ + +static unsigned short +get_homogeneous_type (ffi_type *ty) +{ + if (ty->type == FFI_TYPE_STRUCT && ty->elements) + { + unsigned i; + unsigned short candidate_type + = get_homogeneous_type (ty->elements[0]); + for (i =1; ty->elements[i]; i++) + { + unsigned short iteration_type = 0; + /* If we have a nested struct, we must find its homogeneous type. + If that fits with our candidate type, we are still + homogeneous. */ + if (ty->elements[i]->type == FFI_TYPE_STRUCT + && ty->elements[i]->elements) + { + iteration_type = get_homogeneous_type (ty->elements[i]); + } + else + { + iteration_type = ty->elements[i]->type; + } + + /* If we are not homogeneous, return FFI_TYPE_STRUCT. */ + if (candidate_type != iteration_type) + return FFI_TYPE_STRUCT; + } + return candidate_type; + } + + /* Base case, we have no more levels of nesting, so we + are a basic type, and so, trivially homogeneous in that type. */ + return ty->type; +} + +/* Determine the number of elements within a STRUCT. + + Note, we must handle nested structs. + + If ty is not a STRUCT this function will return 0. */ + +static unsigned +element_count (ffi_type *ty) +{ + if (ty->type == FFI_TYPE_STRUCT && ty->elements) + { + unsigned n; + unsigned elems = 0; + for (n = 0; ty->elements[n]; n++) + { + if (ty->elements[n]->type == FFI_TYPE_STRUCT + && ty->elements[n]->elements) + elems += element_count (ty->elements[n]); + else + elems++; + } + return elems; + } + return 0; +} + +/* Test for a homogeneous floating point aggregate. + + A homogeneous floating point aggregate is a homogeneous aggregate of + a half- single- or double- precision floating point type with one + to four elements. Note that this includes nested structs of the + basic type. */ + +static int +is_hfa (ffi_type *ty) +{ + if (ty->type == FFI_TYPE_STRUCT + && ty->elements[0] + && is_floating_type (get_homogeneous_type (ty))) + { + unsigned n = element_count (ty); + return n >= 1 && n <= 4; + } + return 0; +} + +/* Test if an ffi_type is a candidate for passing in a register. + + This test does not check that sufficient registers of the + appropriate class are actually available, merely that IFF + sufficient registers are available then the argument will be passed + in register(s). + + Note that an ffi_type that is deemed to be a register candidate + will always be returned in registers. + + Returns 1 if a register candidate else 0. */ + +static int +is_register_candidate (ffi_type *ty) +{ + switch (ty->type) + { + case FFI_TYPE_VOID: + case FFI_TYPE_FLOAT: + case FFI_TYPE_DOUBLE: + case FFI_TYPE_LONGDOUBLE: + case FFI_TYPE_UINT8: + case FFI_TYPE_UINT16: + case FFI_TYPE_UINT32: + case FFI_TYPE_UINT64: + case FFI_TYPE_POINTER: + case FFI_TYPE_SINT8: + case FFI_TYPE_SINT16: + case FFI_TYPE_SINT32: + case FFI_TYPE_INT: + case FFI_TYPE_SINT64: + return 1; + + case FFI_TYPE_STRUCT: + if (is_hfa (ty)) + { + return 1; + } + else if (ty->size > 16) + { + /* Too large. Will be replaced with a pointer to memory. The + pointer MAY be passed in a register, but the value will + not. This test specifically fails since the argument will + never be passed by value in registers. */ + return 0; + } + else + { + /* Might be passed in registers depending on the number of + registers required. */ + return (ty->size + 7) / 8 < N_X_ARG_REG; + } + break; + + default: + FFI_ASSERT (0); + break; + } + + return 0; +} + +/* Test if an ffi_type argument or result is a candidate for a vector + register. */ + +static int +is_v_register_candidate (ffi_type *ty) +{ + return is_floating_type (ty->type) + || (ty->type == FFI_TYPE_STRUCT && is_hfa (ty)); +} + +/* Representation of the procedure call argument marshalling + state. + + The terse state variable names match the names used in the AARCH64 + PCS. */ + +struct arg_state +{ + unsigned ngrn; /* Next general-purpose register number. */ + unsigned nsrn; /* Next vector register number. */ + unsigned nsaa; /* Next stack offset. */ +}; + +/* Initialize a procedure call argument marshalling state. */ +static void +arg_init (struct arg_state *state, unsigned call_frame_size) +{ + state->ngrn = 0; + state->nsrn = 0; + state->nsaa = 0; +} + +/* Return the number of available consecutive core argument + registers. */ + +static unsigned +available_x (struct arg_state *state) +{ + return N_X_ARG_REG - state->ngrn; +} + +/* Return the number of available consecutive vector argument + registers. */ + +static unsigned +available_v (struct arg_state *state) +{ + return N_V_ARG_REG - state->nsrn; +} + +static void * +allocate_to_x (struct call_context *context, struct arg_state *state) +{ + FFI_ASSERT (state->ngrn < N_X_ARG_REG) + return get_x_addr (context, (state->ngrn)++); +} + +static void * +allocate_to_s (struct call_context *context, struct arg_state *state) +{ + FFI_ASSERT (state->nsrn < N_V_ARG_REG) + return get_s_addr (context, (state->nsrn)++); +} + +static void * +allocate_to_d (struct call_context *context, struct arg_state *state) +{ + FFI_ASSERT (state->nsrn < N_V_ARG_REG) + return get_d_addr (context, (state->nsrn)++); +} + +static void * +allocate_to_v (struct call_context *context, struct arg_state *state) +{ + FFI_ASSERT (state->nsrn < N_V_ARG_REG) + return get_v_addr (context, (state->nsrn)++); +} + +/* Allocate an aligned slot on the stack and return a pointer to it. */ +static void * +allocate_to_stack (struct arg_state *state, void *stack, unsigned alignment, + unsigned size) +{ + void *allocation; + + /* Round up the NSAA to the larger of 8 or the natural + alignment of the argument's type. */ + state->nsaa = ALIGN (state->nsaa, alignment); + state->nsaa = ALIGN (state->nsaa, alignment); + state->nsaa = ALIGN (state->nsaa, 8); + + allocation = stack + state->nsaa; + + state->nsaa += size; + return allocation; +} + +static void +copy_basic_type (void *dest, void *source, unsigned short type) +{ + /* This is neccessary to ensure that basic types are copied + sign extended to 64-bits as libffi expects. */ + switch (type) + { + case FFI_TYPE_FLOAT: + *(float *) dest = *(float *) source; + break; + case FFI_TYPE_DOUBLE: + *(double *) dest = *(double *) source; + break; + case FFI_TYPE_LONGDOUBLE: + *(long double *) dest = *(long double *) source; + break; + case FFI_TYPE_UINT8: + *(ffi_arg *) dest = *(UINT8 *) source; + break; + case FFI_TYPE_SINT8: + *(ffi_sarg *) dest = *(SINT8 *) source; + break; + case FFI_TYPE_UINT16: + *(ffi_arg *) dest = *(UINT16 *) source; + break; + case FFI_TYPE_SINT16: + *(ffi_sarg *) dest = *(SINT16 *) source; + break; + case FFI_TYPE_UINT32: + *(ffi_arg *) dest = *(UINT32 *) source; + break; + case FFI_TYPE_INT: + case FFI_TYPE_SINT32: + *(ffi_sarg *) dest = *(SINT32 *) source; + break; + case FFI_TYPE_POINTER: + case FFI_TYPE_UINT64: + *(ffi_arg *) dest = *(UINT64 *) source; + break; + case FFI_TYPE_SINT64: + *(ffi_sarg *) dest = *(SINT64 *) source; + break; + + default: + FFI_ASSERT (0); + } +} + +static void +copy_hfa_to_reg_or_stack (void *memory, + ffi_type *ty, + struct call_context *context, + unsigned char *stack, + struct arg_state *state) +{ + unsigned elems = element_count (ty); + if (available_v (state) < elems) + { + /* There are insufficient V registers. Further V register allocations + are prevented, the NSAA is adjusted (by allocate_to_stack ()) + and the argument is copied to memory at the adjusted NSAA. */ + state->nsrn = N_V_ARG_REG; + memcpy (allocate_to_stack (state, stack, ty->alignment, ty->size), + memory, + ty->size); + } + else + { + int i; + unsigned short type = get_homogeneous_type (ty); + unsigned elems = element_count (ty); + for (i = 0; i < elems; i++) + { + void *reg = allocate_to_v (context, state); + copy_basic_type (reg, memory, type); + memory += get_basic_type_size (type); + } + } +} + +/* Either allocate an appropriate register for the argument type, or if + none are available, allocate a stack slot and return a pointer + to the allocated space. */ + +static void * +allocate_to_register_or_stack (struct call_context *context, + unsigned char *stack, + struct arg_state *state, + unsigned short type) +{ + size_t alignment = get_basic_type_alignment (type); + size_t size = alignment; + switch (type) + { + case FFI_TYPE_FLOAT: + /* This is the only case for which the allocated stack size + should not match the alignment of the type. */ + size = sizeof (UINT32); + /* Fall through. */ + case FFI_TYPE_DOUBLE: + if (state->nsrn < N_V_ARG_REG) + return allocate_to_d (context, state); + state->nsrn = N_V_ARG_REG; + break; + case FFI_TYPE_LONGDOUBLE: + if (state->nsrn < N_V_ARG_REG) + return allocate_to_v (context, state); + state->nsrn = N_V_ARG_REG; + break; + case FFI_TYPE_UINT8: + case FFI_TYPE_SINT8: + case FFI_TYPE_UINT16: + case FFI_TYPE_SINT16: + case FFI_TYPE_UINT32: + case FFI_TYPE_SINT32: + case FFI_TYPE_INT: + case FFI_TYPE_POINTER: + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + if (state->ngrn < N_X_ARG_REG) + return allocate_to_x (context, state); + state->ngrn = N_X_ARG_REG; + break; + default: + FFI_ASSERT (0); + } + + return allocate_to_stack (state, stack, alignment, size); +} + +/* Copy a value to an appropriate register, or if none are + available, to the stack. */ + +static void +copy_to_register_or_stack (struct call_context *context, + unsigned char *stack, + struct arg_state *state, + void *value, + unsigned short type) +{ + copy_basic_type ( + allocate_to_register_or_stack (context, stack, state, type), + value, + type); +} + +/* Marshall the arguments from FFI representation to procedure call + context and stack. */ + +static unsigned +aarch64_prep_args (struct call_context *context, unsigned char *stack, + extended_cif *ecif) +{ + int i; + struct arg_state state; + + arg_init (&state, ALIGN(ecif->cif->bytes, 16)); + + for (i = 0; i < ecif->cif->nargs; i++) + { + ffi_type *ty = ecif->cif->arg_types[i]; + switch (ty->type) + { + case FFI_TYPE_VOID: + FFI_ASSERT (0); + break; + + /* If the argument is a basic type the argument is allocated to an + appropriate register, or if none are available, to the stack. */ + case FFI_TYPE_FLOAT: + case FFI_TYPE_DOUBLE: + case FFI_TYPE_LONGDOUBLE: + case FFI_TYPE_UINT8: + case FFI_TYPE_SINT8: + case FFI_TYPE_UINT16: + case FFI_TYPE_SINT16: + case FFI_TYPE_UINT32: + case FFI_TYPE_INT: + case FFI_TYPE_SINT32: + case FFI_TYPE_POINTER: + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + copy_to_register_or_stack (context, stack, &state, + ecif->avalue[i], ty->type); + break; + + case FFI_TYPE_STRUCT: + if (is_hfa (ty)) + { + copy_hfa_to_reg_or_stack (ecif->avalue[i], ty, context, + stack, &state); + } + else if (ty->size > 16) + { + /* If the argument is a composite type that is larger than 16 + bytes, then the argument has been copied to memory, and + the argument is replaced by a pointer to the copy. */ + + copy_to_register_or_stack (context, stack, &state, + &(ecif->avalue[i]), FFI_TYPE_POINTER); + } + else if (available_x (&state) >= (ty->size + 7) / 8) + { + /* If the argument is a composite type and the size in + double-words is not more than the number of available + X registers, then the argument is copied into consecutive + X registers. */ + int j; + for (j = 0; j < (ty->size + 7) / 8; j++) + { + memcpy (allocate_to_x (context, &state), + &(((UINT64 *) ecif->avalue[i])[j]), + sizeof (UINT64)); + } + } + else + { + /* Otherwise, there are insufficient X registers. Further X + register allocations are prevented, the NSAA is adjusted + (by allocate_to_stack ()) and the argument is copied to + memory at the adjusted NSAA. */ + state.ngrn = N_X_ARG_REG; + + memcpy (allocate_to_stack (&state, stack, ty->alignment, + ty->size), ecif->avalue + i, ty->size); + } + break; + + default: + FFI_ASSERT (0); + break; + } + } + + return ecif->cif->aarch64_flags; +} + +ffi_status +ffi_prep_cif_machdep (ffi_cif *cif) +{ + /* Round the stack up to a multiple of the stack alignment requirement. */ + cif->bytes = + (cif->bytes + (AARCH64_STACK_ALIGN - 1)) & ~ (AARCH64_STACK_ALIGN - 1); + + /* Initialize our flags. We are interested if this CIF will touch a + vector register, if so we will enable context save and load to + those registers, otherwise not. This is intended to be friendly + to lazy float context switching in the kernel. */ + cif->aarch64_flags = 0; + + if (is_v_register_candidate (cif->rtype)) + { + cif->aarch64_flags |= AARCH64_FFI_WITH_V; + } + else + { + int i; + for (i = 0; i < cif->nargs; i++) + if (is_v_register_candidate (cif->arg_types[i])) + { + cif->aarch64_flags |= AARCH64_FFI_WITH_V; + break; + } + } + + return FFI_OK; +} + +/* Call a function with the provided arguments and capture the return + value. */ +void +ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) +{ + extended_cif ecif; + + ecif.cif = cif; + ecif.avalue = avalue; + ecif.rvalue = rvalue; + + switch (cif->abi) + { + case FFI_SYSV: + { + struct call_context context; + unsigned stack_bytes; + + /* Figure out the total amount of stack space we need, the + above call frame space needs to be 16 bytes aligned to + ensure correct alignment of the first object inserted in + that space hence the ALIGN applied to cif->bytes.*/ + stack_bytes = ALIGN(cif->bytes, 16); + + memset (&context, 0, sizeof (context)); + if (is_register_candidate (cif->rtype)) + { + ffi_call_SYSV (aarch64_prep_args, &context, &ecif, stack_bytes, fn); + switch (cif->rtype->type) + { + case FFI_TYPE_VOID: + case FFI_TYPE_FLOAT: + case FFI_TYPE_DOUBLE: + case FFI_TYPE_LONGDOUBLE: + case FFI_TYPE_UINT8: + case FFI_TYPE_SINT8: + case FFI_TYPE_UINT16: + case FFI_TYPE_SINT16: + case FFI_TYPE_UINT32: + case FFI_TYPE_SINT32: + case FFI_TYPE_POINTER: + case FFI_TYPE_UINT64: + case FFI_TYPE_INT: + case FFI_TYPE_SINT64: + { + void *addr = get_basic_type_addr (cif->rtype->type, + &context, 0); + copy_basic_type (rvalue, addr, cif->rtype->type); + break; + } + + case FFI_TYPE_STRUCT: + if (is_hfa (cif->rtype)) + { + int j; + unsigned short type = get_homogeneous_type (cif->rtype); + unsigned elems = element_count (cif->rtype); + for (j = 0; j < elems; j++) + { + void *reg = get_basic_type_addr (type, &context, j); + copy_basic_type (rvalue, reg, type); + rvalue += get_basic_type_size (type); + } + } + else if ((cif->rtype->size + 7) / 8 < N_X_ARG_REG) + { + unsigned size = ALIGN (cif->rtype->size, sizeof (UINT64)); + memcpy (rvalue, get_x_addr (&context, 0), size); + } + else + { + FFI_ASSERT (0); + } + break; + + default: + FFI_ASSERT (0); + break; + } + } + else + { + memcpy (get_x_addr (&context, 8), &rvalue, sizeof (UINT64)); + ffi_call_SYSV (aarch64_prep_args, &context, &ecif, + stack_bytes, fn); + } + break; + } + + default: + FFI_ASSERT (0); + break; + } +} + +static unsigned char trampoline [] = +{ 0x70, 0x00, 0x00, 0x58, /* ldr x16, 1f */ + 0x91, 0x00, 0x00, 0x10, /* adr x17, 2f */ + 0x00, 0x02, 0x1f, 0xd6 /* br x16 */ +}; + +/* Build a trampoline. */ + +#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX,FLAGS) \ + ({unsigned char *__tramp = (unsigned char*)(TRAMP); \ + UINT64 __fun = (UINT64)(FUN); \ + UINT64 __ctx = (UINT64)(CTX); \ + UINT64 __flags = (UINT64)(FLAGS); \ + memcpy (__tramp, trampoline, sizeof (trampoline)); \ + memcpy (__tramp + 12, &__fun, sizeof (__fun)); \ + memcpy (__tramp + 20, &__ctx, sizeof (__ctx)); \ + memcpy (__tramp + 28, &__flags, sizeof (__flags)); \ + __clear_cache(__tramp, __tramp + FFI_TRAMPOLINE_SIZE); \ + }) + +ffi_status +ffi_prep_closure_loc (ffi_closure* closure, + ffi_cif* cif, + void (*fun)(ffi_cif*,void*,void**,void*), + void *user_data, + void *codeloc) +{ + if (cif->abi != FFI_SYSV) + return FFI_BAD_ABI; + + FFI_INIT_TRAMPOLINE (&closure->tramp[0], &ffi_closure_SYSV, codeloc, + cif->aarch64_flags); + + closure->cif = cif; + closure->user_data = user_data; + closure->fun = fun; + + return FFI_OK; +} + +/* Primary handler to setup and invoke a function within a closure. + + A closure when invoked enters via the assembler wrapper + ffi_closure_SYSV(). The wrapper allocates a call context on the + stack, saves the interesting registers (from the perspective of + the calling convention) into the context then passes control to + ffi_closure_SYSV_inner() passing the saved context and a pointer to + the stack at the point ffi_closure_SYSV() was invoked. + + On the return path the assembler wrapper will reload call context + regsiters. + + ffi_closure_SYSV_inner() marshalls the call context into ffi value + desriptors, invokes the wrapped function, then marshalls the return + value back into the call context. */ + +void +ffi_closure_SYSV_inner (ffi_closure *closure, struct call_context *context, + void *stack) +{ + ffi_cif *cif = closure->cif; + void **avalue = (void**) alloca (cif->nargs * sizeof (void*)); + void *rvalue = NULL; + int i; + struct arg_state state; + + arg_init (&state, ALIGN(cif->bytes, 16)); + + for (i = 0; i < cif->nargs; i++) + { + ffi_type *ty = cif->arg_types[i]; + + switch (ty->type) + { + case FFI_TYPE_VOID: + FFI_ASSERT (0); + break; + + case FFI_TYPE_UINT8: + case FFI_TYPE_SINT8: + case FFI_TYPE_UINT16: + case FFI_TYPE_SINT16: + case FFI_TYPE_UINT32: + case FFI_TYPE_SINT32: + case FFI_TYPE_INT: + case FFI_TYPE_POINTER: + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + case FFI_TYPE_FLOAT: + case FFI_TYPE_DOUBLE: + case FFI_TYPE_LONGDOUBLE: + avalue[i] = allocate_to_register_or_stack (context, stack, + &state, ty->type); + break; + + case FFI_TYPE_STRUCT: + if (is_hfa (ty)) + { + unsigned n = element_count (ty); + if (available_v (&state) < n) + { + state.nsrn = N_V_ARG_REG; + avalue[i] = allocate_to_stack (&state, stack, ty->alignment, + ty->size); + } + else + { + switch (get_homogeneous_type (ty)) + { + case FFI_TYPE_FLOAT: + { + /* Eeek! We need a pointer to the structure, + however the homogeneous float elements are + being passed in individual S registers, + therefore the structure is not represented as + a contiguous sequence of bytes in our saved + register context. We need to fake up a copy + of the structure layed out in memory + correctly. The fake can be tossed once the + closure function has returned hence alloca() + is sufficient. */ + int j; + UINT32 *p = avalue[i] = alloca (ty->size); + for (j = 0; j < element_count (ty); j++) + memcpy (&p[j], + allocate_to_s (context, &state), + sizeof (*p)); + break; + } + + case FFI_TYPE_DOUBLE: + { + /* Eeek! We need a pointer to the structure, + however the homogeneous float elements are + being passed in individual S registers, + therefore the structure is not represented as + a contiguous sequence of bytes in our saved + register context. We need to fake up a copy + of the structure layed out in memory + correctly. The fake can be tossed once the + closure function has returned hence alloca() + is sufficient. */ + int j; + UINT64 *p = avalue[i] = alloca (ty->size); + for (j = 0; j < element_count (ty); j++) + memcpy (&p[j], + allocate_to_d (context, &state), + sizeof (*p)); + break; + } + + case FFI_TYPE_LONGDOUBLE: + memcpy (&avalue[i], + allocate_to_v (context, &state), + sizeof (*avalue)); + break; + + default: + FFI_ASSERT (0); + break; + } + } + } + else if (ty->size > 16) + { + /* Replace Composite type of size greater than 16 with a + pointer. */ + memcpy (&avalue[i], + allocate_to_register_or_stack (context, stack, + &state, FFI_TYPE_POINTER), + sizeof (avalue[i])); + } + else if (available_x (&state) >= (ty->size + 7) / 8) + { + avalue[i] = get_x_addr (context, state.ngrn); + state.ngrn += (ty->size + 7) / 8; + } + else + { + state.ngrn = N_X_ARG_REG; + + avalue[i] = allocate_to_stack (&state, stack, ty->alignment, + ty->size); + } + break; + + default: + FFI_ASSERT (0); + break; + } + } + + /* Figure out where the return value will be passed, either in + registers or in a memory block allocated by the caller and passed + in x8. */ + + if (is_register_candidate (cif->rtype)) + { + /* Register candidates are *always* returned in registers. */ + + /* Allocate a scratchpad for the return value, we will let the + callee scrible the result into the scratch pad then move the + contents into the appropriate return value location for the + call convention. */ + rvalue = alloca (cif->rtype->size); + (closure->fun) (cif, rvalue, avalue, closure->user_data); + + /* Copy the return value into the call context so that it is returned + as expected to our caller. */ + switch (cif->rtype->type) + { + case FFI_TYPE_VOID: + break; + + case FFI_TYPE_UINT8: + case FFI_TYPE_UINT16: + case FFI_TYPE_UINT32: + case FFI_TYPE_POINTER: + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT8: + case FFI_TYPE_SINT16: + case FFI_TYPE_INT: + case FFI_TYPE_SINT32: + case FFI_TYPE_SINT64: + case FFI_TYPE_FLOAT: + case FFI_TYPE_DOUBLE: + case FFI_TYPE_LONGDOUBLE: + { + void *addr = get_basic_type_addr (cif->rtype->type, context, 0); + copy_basic_type (addr, rvalue, cif->rtype->type); + break; + } + case FFI_TYPE_STRUCT: + if (is_hfa (cif->rtype)) + { + int i; + unsigned short type = get_homogeneous_type (cif->rtype); + unsigned elems = element_count (cif->rtype); + for (i = 0; i < elems; i++) + { + void *reg = get_basic_type_addr (type, context, i); + copy_basic_type (reg, rvalue, type); + rvalue += get_basic_type_size (type); + } + } + else if ((cif->rtype->size + 7) / 8 < N_X_ARG_REG) + { + unsigned size = ALIGN (cif->rtype->size, sizeof (UINT64)) ; + memcpy (get_x_addr (context, 0), rvalue, size); + } + else + { + FFI_ASSERT (0); + } + break; + default: + FFI_ASSERT (0); + break; + } + } + else + { + memcpy (&rvalue, get_x_addr (context, 8), sizeof (UINT64)); + (closure->fun) (cif, rvalue, avalue, closure->user_data); + } +} + diff --git a/libffi/src/aarch64/ffitarget.h b/libffi/src/aarch64/ffitarget.h new file mode 100644 index 0000000..6f1a348 --- /dev/null +++ b/libffi/src/aarch64/ffitarget.h @@ -0,0 +1,59 @@ +/* Copyright (c) 2009, 2010, 2011, 2012 ARM Ltd. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +``Software''), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef LIBFFI_TARGET_H +#define LIBFFI_TARGET_H + +#ifndef LIBFFI_H +#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." +#endif + +#ifndef LIBFFI_ASM +typedef unsigned long ffi_arg; +typedef signed long ffi_sarg; + +typedef enum ffi_abi + { + FFI_FIRST_ABI = 0, + FFI_SYSV, + FFI_LAST_ABI, + FFI_DEFAULT_ABI = FFI_SYSV + } ffi_abi; +#endif + +/* ---- Definitions for closures ----------------------------------------- */ + +#define FFI_CLOSURES 1 +#define FFI_TRAMPOLINE_SIZE 36 +#define FFI_NATIVE_RAW_API 0 + +/* ---- Internal ---- */ + + +#define FFI_EXTRA_CIF_FIELDS unsigned aarch64_flags + +#define AARCH64_FFI_WITH_V_BIT 0 + +#define AARCH64_N_XREG 32 +#define AARCH64_N_VREG 32 +#define AARCH64_CALL_CONTEXT_SIZE (AARCH64_N_XREG * 8 + AARCH64_N_VREG * 16) + +#endif diff --git a/libffi/src/aarch64/sysv.S b/libffi/src/aarch64/sysv.S new file mode 100644 index 0000000..b8cd421 --- /dev/null +++ b/libffi/src/aarch64/sysv.S @@ -0,0 +1,307 @@ +/* Copyright (c) 2009, 2010, 2011, 2012 ARM Ltd. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +``Software''), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#define LIBFFI_ASM +#include +#include + +#define cfi_adjust_cfa_offset(off) .cfi_adjust_cfa_offset off +#define cfi_rel_offset(reg, off) .cfi_rel_offset reg, off +#define cfi_restore(reg) .cfi_restore reg +#define cfi_def_cfa_register(reg) .cfi_def_cfa_register reg + + .text + .globl ffi_call_SYSV + .type ffi_call_SYSV, #function + +/* ffi_call_SYSV() + + Create a stack frame, setup an argument context, call the callee + and extract the result. + + The maximum required argument stack size is provided, + ffi_call_SYSV() allocates that stack space then calls the + prepare_fn to populate register context and stack. The + argument passing registers are loaded from the register + context and the callee called, on return the register passing + register are saved back to the context. Our caller will + extract the return value from the final state of the saved + register context. + + Prototype: + + extern unsigned + ffi_call_SYSV (void (*)(struct call_context *context, unsigned char *, + extended_cif *), + struct call_context *context, + extended_cif *, + unsigned required_stack_size, + void (*fn)(void)); + + Therefore on entry we have: + + x0 prepare_fn + x1 &context + x2 &ecif + x3 bytes + x4 fn + + This function uses the following stack frame layout: + + == + saved x30(lr) + x29(fp)-> saved x29(fp) + saved x24 + saved x23 + saved x22 + sp' -> saved x21 + ... + sp -> (constructed callee stack arguments) + == + + Voila! */ + +#define ffi_call_SYSV_FS (8 * 4) + + .cfi_startproc +ffi_call_SYSV: + stp x29, x30, [sp, #-16]! + cfi_adjust_cfa_offset (16) + cfi_rel_offset (x29, 0) + cfi_rel_offset (x30, 8) + + mov x29, sp + cfi_def_cfa_register (x29) + sub sp, sp, #ffi_call_SYSV_FS + + stp x21, x22, [sp, 0] + cfi_rel_offset (x21, 0 - ffi_call_SYSV_FS) + cfi_rel_offset (x22, 8 - ffi_call_SYSV_FS) + + stp x23, x24, [sp, 16] + cfi_rel_offset (x23, 16 - ffi_call_SYSV_FS) + cfi_rel_offset (x24, 24 - ffi_call_SYSV_FS) + + mov x21, x1 + mov x22, x2 + mov x24, x4 + + /* Allocate the stack space for the actual arguments, many + arguments will be passed in registers, but we assume + worst case and allocate sufficient stack for ALL of + the arguments. */ + sub sp, sp, x3 + + /* unsigned (*prepare_fn) (struct call_context *context, + unsigned char *stack, extended_cif *ecif); + */ + mov x23, x0 + mov x0, x1 + mov x1, sp + /* x2 already in place */ + blr x23 + + /* Preserve the flags returned. */ + mov x23, x0 + + /* Figure out if we should touch the vector registers. */ + tbz x23, #AARCH64_FFI_WITH_V_BIT, 1f + + /* Load the vector argument passing registers. */ + ldp q0, q1, [x21, #8*32 + 0] + ldp q2, q3, [x21, #8*32 + 32] + ldp q4, q5, [x21, #8*32 + 64] + ldp q6, q7, [x21, #8*32 + 96] +1: + /* Load the core argument passing registers. */ + ldp x0, x1, [x21, #0] + ldp x2, x3, [x21, #16] + ldp x4, x5, [x21, #32] + ldp x6, x7, [x21, #48] + + /* Don't forget x8 which may be holding the address of a return buffer. + */ + ldr x8, [x21, #8*8] + + blr x24 + + /* Save the core argument passing registers. */ + stp x0, x1, [x21, #0] + stp x2, x3, [x21, #16] + stp x4, x5, [x21, #32] + stp x6, x7, [x21, #48] + + /* Note nothing useful ever comes back in x8! */ + + /* Figure out if we should touch the vector registers. */ + tbz x23, #AARCH64_FFI_WITH_V_BIT, 1f + + /* Save the vector argument passing registers. */ + stp q0, q1, [x21, #8*32 + 0] + stp q2, q3, [x21, #8*32 + 32] + stp q4, q5, [x21, #8*32 + 64] + stp q6, q7, [x21, #8*32 + 96] +1: + /* All done, unwind our stack frame. */ + ldp x21, x22, [x29, # - ffi_call_SYSV_FS] + cfi_restore (x21) + cfi_restore (x22) + + ldp x23, x24, [x29, # - ffi_call_SYSV_FS + 16] + cfi_restore (x23) + cfi_restore (x24) + + mov sp, x29 + cfi_def_cfa_register (sp) + + ldp x29, x30, [sp], #16 + cfi_adjust_cfa_offset (-16) + cfi_restore (x29) + cfi_restore (x30) + + ret + + .cfi_endproc + .size ffi_call_SYSV, .-ffi_call_SYSV + +#define ffi_closure_SYSV_FS (8 * 2 + AARCH64_CALL_CONTEXT_SIZE) + +/* ffi_closure_SYSV + + Closure invocation glue. This is the low level code invoked directly by + the closure trampoline to setup and call a closure. + + On entry x17 points to a struct trampoline_data, x16 has been clobbered + all other registers are preserved. + + We allocate a call context and save the argument passing registers, + then invoked the generic C ffi_closure_SYSV_inner() function to do all + the real work, on return we load the result passing registers back from + the call context. + + On entry + + extern void + ffi_closure_SYSV (struct trampoline_data *); + + struct trampoline_data + { + UINT64 *ffi_closure; + UINT64 flags; + }; + + This function uses the following stack frame layout: + + == + saved x30(lr) + x29(fp)-> saved x29(fp) + saved x22 + saved x21 + ... + sp -> call_context + == + + Voila! */ + + .text + .globl ffi_closure_SYSV + .cfi_startproc +ffi_closure_SYSV: + stp x29, x30, [sp, #-16]! + cfi_adjust_cfa_offset (16) + cfi_rel_offset (x29, 0) + cfi_rel_offset (x30, 8) + + mov x29, sp + + sub sp, sp, #ffi_closure_SYSV_FS + cfi_adjust_cfa_offset (ffi_closure_SYSV_FS) + + stp x21, x22, [x29, #-16] + cfi_rel_offset (x21, 0) + cfi_rel_offset (x22, 8) + + /* Load x21 with &call_context. */ + mov x21, sp + /* Preserve our struct trampoline_data * */ + mov x22, x17 + + /* Save the rest of the argument passing registers. */ + stp x0, x1, [x21, #0] + stp x2, x3, [x21, #16] + stp x4, x5, [x21, #32] + stp x6, x7, [x21, #48] + /* Don't forget we may have been given a result scratch pad address. + */ + str x8, [x21, #64] + + /* Figure out if we should touch the vector registers. */ + ldr x0, [x22, #8] + tbz x0, #AARCH64_FFI_WITH_V_BIT, 1f + + /* Save the argument passing vector registers. */ + stp q0, q1, [x21, #8*32 + 0] + stp q2, q3, [x21, #8*32 + 32] + stp q4, q5, [x21, #8*32 + 64] + stp q6, q7, [x21, #8*32 + 96] +1: + /* Load &ffi_closure.. */ + ldr x0, [x22, #0] + mov x1, x21 + /* Compute the location of the stack at the point that the + trampoline was called. */ + add x2, x29, #16 + + bl ffi_closure_SYSV_inner + + /* Figure out if we should touch the vector registers. */ + ldr x0, [x22, #8] + tbz x0, #AARCH64_FFI_WITH_V_BIT, 1f + + /* Load the result passing vector registers. */ + ldp q0, q1, [x21, #8*32 + 0] + ldp q2, q3, [x21, #8*32 + 32] + ldp q4, q5, [x21, #8*32 + 64] + ldp q6, q7, [x21, #8*32 + 96] +1: + /* Load the result passing core registers. */ + ldp x0, x1, [x21, #0] + ldp x2, x3, [x21, #16] + ldp x4, x5, [x21, #32] + ldp x6, x7, [x21, #48] + /* Note nothing usefull is returned in x8. */ + + /* We are done, unwind our frame. */ + ldp x21, x22, [x29, #-16] + cfi_restore (x21) + cfi_restore (x22) + + mov sp, x29 + cfi_adjust_cfa_offset (-ffi_closure_SYSV_FS) + + ldp x29, x30, [sp], #16 + cfi_adjust_cfa_offset (-16) + cfi_restore (x29) + cfi_restore (x30) + + ret + .cfi_endproc + .size ffi_closure_SYSV, .-ffi_closure_SYSV diff --git a/libffi/src/arm/ffi.c b/libffi/src/arm/ffi.c index 1f8597d..3ccceb9 100644 --- a/libffi/src/arm/ffi.c +++ b/libffi/src/arm/ffi.c @@ -251,8 +251,10 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) break; case FFI_VFP: +#ifdef __ARM_EABI__ ffi_call_VFP (fn, &ecif, cif->bytes, cif->flags, ecif.rvalue); break; +#endif default: FFI_ASSERT(0); @@ -609,8 +611,10 @@ ffi_prep_closure_loc (ffi_closure* closure, if (cif->abi == FFI_SYSV) closure_func = &ffi_closure_SYSV; +#ifdef __ARM_EABI__ else if (cif->abi == FFI_VFP) closure_func = &ffi_closure_VFP; +#endif else return FFI_BAD_ABI; diff --git a/libffi/src/arm/sysv.S b/libffi/src/arm/sysv.S index 60e2ae3..fb38cd6 100644 --- a/libffi/src/arm/sysv.S +++ b/libffi/src/arm/sysv.S @@ -41,7 +41,7 @@ #define CNAME(x) x #endif #ifdef __APPLE__ -#define ENTRY(x) .globl CNAME(x); CNAME(x): +#define ENTRY(x) .globl _##x; _##x: #else #define ENTRY(x) .globl CNAME(x); .type CNAME(x),%function; CNAME(x): #endif /* __APPLE__ */ @@ -187,7 +187,7 @@ ARM_FUNC_START ffi_call_SYSV @ r1 already set @ Call ffi_prep_args(stack, &ecif) - bl ffi_prep_args + bl CNAME(ffi_prep_args) @ move first 4 parameters in registers ldmia sp, {r0-r3} @@ -334,7 +334,9 @@ ARM_FUNC_START ffi_closure_SYSV /* Below are VFP hard-float ABI call and closure implementations. - Add VFP FPU directive here. */ + Add VFP FPU directive here. This is only compiled into the library + under EABI. */ +#ifdef __ARM_EABI__ .fpu vfp @ r0: fn @@ -362,7 +364,7 @@ ARM_FUNC_START ffi_call_VFP sub r2, fp, #64 @ VFP scratch space @ Call ffi_prep_args(stack, &ecif, vfp_space) - bl ffi_prep_args + bl CNAME(ffi_prep_args) @ Load VFP register args if needed cmp r0, #0 @@ -444,7 +446,7 @@ ARM_FUNC_START ffi_closure_VFP sub sp, sp, #72 str sp, [sp, #64] add r1, sp, #64 - bl ffi_closure_SYSV_inner + bl CNAME(ffi_closure_SYSV_inner) cmp r0, #FFI_TYPE_INT beq .Lretint_vfp @@ -491,6 +493,7 @@ ARM_FUNC_START ffi_closure_VFP .ffi_closure_VFP_end: UNWIND .fnend .size CNAME(ffi_closure_VFP),.ffi_closure_VFP_end-CNAME(ffi_closure_VFP) +#endif ENTRY(ffi_arm_trampoline) stmfd sp!, {r0-r3} diff --git a/libffi/src/arm/trampoline.S b/libffi/src/arm/trampoline.S index 7b47429..935e8de 100644 --- a/libffi/src/arm/trampoline.S +++ b/libffi/src/arm/trampoline.S @@ -1,5 +1,5 @@ # GENERATED CODE - DO NOT EDIT -# This file was generated by ./gentramp.sh +# This file was generated by src/arm/gentramp.sh # Copyright (c) 2010, Plausible Labs Cooperative, Inc. # diff --git a/libffi/src/bfin/ffi.c b/libffi/src/bfin/ffi.c new file mode 100644 index 0000000..0beccc1 --- /dev/null +++ b/libffi/src/bfin/ffi.c @@ -0,0 +1,195 @@ +/* ----------------------------------------------------------------------- + ffi.c - Copyright (c) 2012 Alexandre K. I. de Mendonca + + Blackfin Foreign Function Interface + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + ----------------------------------------------------------------------- */ +#include +#include + +#include +#include + +/* Maximum number of GPRs available for argument passing. */ +#define MAX_GPRARGS 3 + +/* + * Return types + */ +#define FFIBFIN_RET_VOID 0 +#define FFIBFIN_RET_BYTE 1 +#define FFIBFIN_RET_HALFWORD 2 +#define FFIBFIN_RET_INT64 3 +#define FFIBFIN_RET_INT32 4 + +/*====================================================================*/ +/* PROTOTYPE * + /*====================================================================*/ +void ffi_prep_args(unsigned char *, extended_cif *); + +/*====================================================================*/ +/* Externals */ +/* (Assembly) */ +/*====================================================================*/ + +extern void ffi_call_SYSV(unsigned, extended_cif *, void(*)(unsigned char *, extended_cif *), unsigned, void *, void(*fn)(void)); + +/*====================================================================*/ +/* Implementation */ +/* */ +/*====================================================================*/ + + +/* + * This function calculates the return type (size) based on type. + */ + +ffi_status ffi_prep_cif_machdep(ffi_cif *cif) +{ + /* --------------------------------------* + * Return handling * + * --------------------------------------*/ + switch (cif->rtype->type) { + case FFI_TYPE_VOID: + cif->flags = FFIBFIN_RET_VOID; + break; + case FFI_TYPE_UINT16: + case FFI_TYPE_SINT16: + cif->flags = FFIBFIN_RET_HALFWORD; + break; + case FFI_TYPE_UINT8: + cif->flags = FFIBFIN_RET_BYTE; + break; + case FFI_TYPE_INT: + case FFI_TYPE_UINT32: + case FFI_TYPE_SINT32: + case FFI_TYPE_FLOAT: + case FFI_TYPE_POINTER: + case FFI_TYPE_SINT8: + cif->flags = FFIBFIN_RET_INT32; + break; + case FFI_TYPE_SINT64: + case FFI_TYPE_UINT64: + case FFI_TYPE_DOUBLE: + cif->flags = FFIBFIN_RET_INT64; + break; + case FFI_TYPE_STRUCT: + if (cif->rtype->size <= 4){ + cif->flags = FFIBFIN_RET_INT32; + }else if (cif->rtype->size == 8){ + cif->flags = FFIBFIN_RET_INT64; + }else{ + //it will return via a hidden pointer in P0 + cif->flags = FFIBFIN_RET_VOID; + } + break; + default: + FFI_ASSERT(0); + break; + } + return FFI_OK; +} + +/* + * This will prepare the arguments and will call the assembly routine + * cif = the call interface + * fn = the function to be called + * rvalue = the return value + * avalue = the arguments + */ +void ffi_call(ffi_cif *cif, void(*fn)(void), void *rvalue, void **avalue) +{ + int ret_type = cif->flags; + extended_cif ecif; + ecif.cif = cif; + ecif.avalue = avalue; + ecif.rvalue = rvalue; + + switch (cif->abi) { + case FFI_SYSV: + ffi_call_SYSV(cif->bytes, &ecif, ffi_prep_args, ret_type, ecif.rvalue, fn); + break; + default: + FFI_ASSERT(0); + break; + } +} + + +/* +* This function prepares the parameters (copies them from the ecif to the stack) +* to call the function (ffi_prep_args is called by the assembly routine in file +* sysv.S, which also calls the actual function) +*/ +void ffi_prep_args(unsigned char *stack, extended_cif *ecif) +{ + register unsigned int i = 0; + void **p_argv; + unsigned char *argp; + ffi_type **p_arg; + argp = stack; + p_argv = ecif->avalue; + for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; + (i != 0); + i--, p_arg++) { + size_t z; + z = (*p_arg)->size; + if (z < sizeof(int)) { + z = sizeof(int); + switch ((*p_arg)->type) { + case FFI_TYPE_SINT8: { + signed char v = *(SINT8 *)(* p_argv); + signed int t = v; + *(signed int *) argp = t; + } + break; + case FFI_TYPE_UINT8: { + unsigned char v = *(UINT8 *)(* p_argv); + unsigned int t = v; + *(unsigned int *) argp = t; + } + break; + case FFI_TYPE_SINT16: + *(signed int *) argp = (signed int) * (SINT16 *)(* p_argv); + break; + case FFI_TYPE_UINT16: + *(unsigned int *) argp = (unsigned int) * (UINT16 *)(* p_argv); + break; + case FFI_TYPE_STRUCT: + memcpy(argp, *p_argv, (*p_arg)->size); + break; + default: + FFI_ASSERT(0); + break; + } + } else if (z == sizeof(int)) { + *(unsigned int *) argp = (unsigned int) * (UINT32 *)(* p_argv); + } else { + memcpy(argp, *p_argv, z); + } + p_argv++; + argp += z; + } +} + + + diff --git a/libffi/src/bfin/ffitarget.h b/libffi/src/bfin/ffitarget.h new file mode 100644 index 0000000..2175c01 --- /dev/null +++ b/libffi/src/bfin/ffitarget.h @@ -0,0 +1,43 @@ +/* ----------------------------------------------------------------------- + ffitarget.h - Copyright (c) 2012 Alexandre K. I. de Mendonca + + Blackfin Foreign Function Interface + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + ----------------------------------------------------------------------- */ + +#ifndef LIBFFI_TARGET_H +#define LIBFFI_TARGET_H + +#ifndef LIBFFI_ASM +typedef unsigned long ffi_arg; +typedef signed long ffi_sarg; + +typedef enum ffi_abi { + FFI_FIRST_ABI = 0, + FFI_SYSV, + FFI_LAST_ABI, + FFI_DEFAULT_ABI = FFI_SYSV +} ffi_abi; +#endif + +#endif + diff --git a/libffi/src/bfin/sysv.S b/libffi/src/bfin/sysv.S new file mode 100644 index 0000000..ae7a152 --- /dev/null +++ b/libffi/src/bfin/sysv.S @@ -0,0 +1,177 @@ +/* ----------------------------------------------------------------------- + sysv.S - Copyright (c) 2012 Alexandre K. I. de Mendonca + + Blackfin Foreign Function Interface + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + ----------------------------------------------------------------------- */ + +#define LIBFFI_ASM +#include +#include + +.text +.align 4 + + /* + There is a "feature" in the bfin toolchain that it puts a _ before funcion names + that's why the function here it's called _ffi_call_SYSV and not ffi_call_SYSV + */ + .global _ffi_call_SYSV; + .type _ffi_call_SYSV, STT_FUNC; + .func ffi_call_SYSV + + /* + cif->bytes = R0 (fp+8) + &ecif = R1 (fp+12) + ffi_prep_args = R2 (fp+16) + ret_type = stack (fp+20) + ecif.rvalue = stack (fp+24) + fn = stack (fp+28) + got (fp+32) + There is room for improvement here (we can use temporary registers + instead of saving the values in the memory) + REGS: + P5 => Stack pointer (function arguments) + R5 => cif->bytes + R4 => ret->type + + FP-20 = P3 + FP-16 = SP (parameters area) + FP-12 = SP (temp) + FP-08 = function return part 1 [R0] + FP-04 = function return part 2 [R1] + */ + +_ffi_call_SYSV: +.prologue: + LINK 20; + [FP-20] = P3; + [FP+8] = R0; + [FP+12] = R1; + [FP+16] = R2; + +.allocate_stack: + //alocate cif->bytes into the stack + R1 = [FP+8]; + R0 = SP; + R0 = R0 - R1; + R1 = 4; + R0 = R0 - R1; + [FP-12] = SP; + SP = R0; + [FP-16] = SP; + +.call_prep_args: + //get the addr of prep_args + P0 = [P3 + _ffi_prep_args@FUNCDESC_GOT17M4]; + P1 = [P0]; + P3 = [P0+4]; + R0 = [FP-16];//SP (parameter area) + R1 = [FP+12];//ecif + call (P1); + +.call_user_function: + //ajust SP so as to allow the user function access the parameters on the stack + SP = [FP-16]; //point to function parameters + R0 = [SP]; + R1 = [SP+4]; + R2 = [SP+8]; + //load user function address + P0 = FP; + P0 +=28; + P1 = [P0]; + P1 = [P1]; + P3 = [P0+4]; + /* + For functions returning aggregate values (struct) occupying more than 8 bytes, + the caller allocates the return value object on the stack and the address + of this object is passed to the callee as a hidden argument in register P0. + */ + P0 = [FP+24]; + + call (P1); + SP = [FP-12]; +.compute_return: + P2 = [FP-20]; + [FP-8] = R0; + [FP-4] = R1; + + R0 = [FP+20]; + R1 = R0 << 2; + + R0 = [P2+.rettable@GOT17M4]; + R0 = R1 + R0; + P2 = R0; + R1 = [P2]; + + P2 = [FP+-20]; + R0 = [P2+.rettable@GOT17M4]; + R0 = R1 + R0; + P2 = R0; + R0 = [FP-8]; + R1 = [FP-4]; + jump (P2); + +/* +#define FFIBFIN_RET_VOID 0 +#define FFIBFIN_RET_BYTE 1 +#define FFIBFIN_RET_HALFWORD 2 +#define FFIBFIN_RET_INT64 3 +#define FFIBFIN_RET_INT32 4 +*/ +.align 4 +.align 4 +.rettable: + .dd .epilogue - .rettable + .dd .rbyte - .rettable; + .dd .rhalfword - .rettable; + .dd .rint64 - .rettable; + .dd .rint32 - .rettable; + +.rbyte: + P0 = [FP+24]; + R0 = R0.B (Z); + [P0] = R0; + JUMP .epilogue +.rhalfword: + P0 = [FP+24]; + R0 = R0.L; + [P0] = R0; + JUMP .epilogue +.rint64: + P0 = [FP+24];// &rvalue + [P0] = R0; + [P0+4] = R1; + JUMP .epilogue +.rint32: + P0 = [FP+24]; + [P0] = R0; +.epilogue: + R0 = [FP+8]; + R1 = [FP+12]; + R2 = [FP+16]; + P3 = [FP-20]; + UNLINK; + RTS; + +.size _ffi_call_SYSV,.-_ffi_call_SYSV; +.endfunc diff --git a/libffi/src/closures.c b/libffi/src/closures.c index 1b37827..fecbc4a 100644 --- a/libffi/src/closures.c +++ b/libffi/src/closures.c @@ -172,6 +172,27 @@ selinux_enabled_check (void) #endif /* !FFI_MMAP_EXEC_SELINUX */ +/* On PaX enable kernels that have MPROTECT enable we can't use PROT_EXEC. */ +#ifdef FFI_MMAP_EXEC_EMUTRAMP_PAX +#include + +static int emutramp_enabled = -1; + +static int +emutramp_enabled_check (void) +{ + if (getenv ("FFI_DISABLE_EMUTRAMP") == NULL) + return 1; + else + return 0; +} + +#define is_emutramp_enabled() (emutramp_enabled >= 0 ? emutramp_enabled \ + : (emutramp_enabled = emutramp_enabled_check ())) +#else +#define is_emutramp_enabled() 0 +#endif /* FFI_MMAP_EXEC_EMUTRAMP_PAX */ + #elif defined (__CYGWIN__) || defined(__INTERIX) #include @@ -458,6 +479,12 @@ dlmmap (void *start, size_t length, int prot, printf ("mapping in %zi\n", length); #endif + if (execfd == -1 && is_emutramp_enabled ()) + { + ptr = mmap (start, length, prot & ~PROT_EXEC, flags, fd, offset); + return ptr; + } + if (execfd == -1 && !is_selinux_enabled ()) { ptr = mmap (start, length, prot | PROT_EXEC, flags, fd, offset); diff --git a/libffi/src/m68k/ffi.c b/libffi/src/m68k/ffi.c index d95c72b..37a0784 100644 --- a/libffi/src/m68k/ffi.c +++ b/libffi/src/m68k/ffi.c @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------- ffi.c - - m68k Foreign Function Interface + + m68k Foreign Function Interface ----------------------------------------------------------------------- */ #include @@ -13,8 +13,13 @@ void rtems_cache_flush_multiple_data_lines( const void *, size_t ); #else #include +#ifdef __MINT__ +#include +#include +#else #include #endif +#endif void ffi_call_SYSV (extended_cif *, unsigned, unsigned, @@ -39,8 +44,12 @@ ffi_prep_args (void *stack, extended_cif *ecif) argp = stack; - if (ecif->cif->rtype->type == FFI_TYPE_STRUCT - && !ecif->cif->flags) + if ( +#ifdef __MINT__ + (ecif->cif->rtype->type == FFI_TYPE_LONGDOUBLE) || +#endif + (((ecif->cif->rtype->type == FFI_TYPE_STRUCT) + && !ecif->cif->flags))) struct_value_ptr = ecif->rvalue; else struct_value_ptr = NULL; @@ -51,12 +60,12 @@ ffi_prep_args (void *stack, extended_cif *ecif) i != 0; i--, p_arg++) { - size_t z; + size_t z = (*p_arg)->size; + int type = (*p_arg)->type; - z = (*p_arg)->size; if (z < sizeof (int)) { - switch ((*p_arg)->type) + switch (type) { case FFI_TYPE_SINT8: *(signed int *) argp = (signed int) *(SINT8 *) *p_argv; @@ -75,7 +84,14 @@ ffi_prep_args (void *stack, extended_cif *ecif) break; case FFI_TYPE_STRUCT: +#ifdef __MINT__ + if (z == 1 || z == 2) + memcpy (argp + 2, *p_argv, z); + else + memcpy (argp, *p_argv, z); +#else memcpy (argp + sizeof (int) - z, *p_argv, z); +#endif break; default: @@ -120,17 +136,34 @@ ffi_prep_cif_machdep (ffi_cif *cif) break; case FFI_TYPE_STRUCT: + if (cif->rtype->elements[0]->type == FFI_TYPE_STRUCT && + cif->rtype->elements[1]) + { + cif->flags = 0; + break; + } + switch (cif->rtype->size) { case 1: +#ifdef __MINT__ + cif->flags = CIF_FLAGS_STRUCT2; +#else cif->flags = CIF_FLAGS_STRUCT1; +#endif break; case 2: cif->flags = CIF_FLAGS_STRUCT2; break; +#ifdef __MINT__ + case 3: +#endif case 4: cif->flags = CIF_FLAGS_INT; break; +#ifdef __MINT__ + case 7: +#endif case 8: cif->flags = CIF_FLAGS_DINT; break; @@ -150,7 +183,11 @@ ffi_prep_cif_machdep (ffi_cif *cif) #if (FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE) case FFI_TYPE_LONGDOUBLE: +#ifdef __MINT__ + cif->flags = 0; +#else cif->flags = CIF_FLAGS_LDOUBLE; +#endif break; #endif @@ -218,6 +255,26 @@ ffi_prep_incoming_args_SYSV (char *stack, void **avalue, ffi_cif *cif) size_t z; z = (*p_arg)->size; +#ifdef __MINT__ + if (cif->flags && + cif->rtype->type == FFI_TYPE_STRUCT && + (z == 1 || z == 2)) + { + *p_argv = (void *) (argp + 2); + + z = 4; + } + else + if (cif->flags && + cif->rtype->type == FFI_TYPE_STRUCT && + (z == 3 || z == 4)) + { + *p_argv = (void *) (argp); + + z = 4; + } + else +#endif if (z <= 4) { *p_argv = (void *) (argp + 4 - z); @@ -267,14 +324,21 @@ ffi_prep_closure_loc (ffi_closure* closure, *(unsigned short *)closure->tramp = 0x207c; *(void **)(closure->tramp + 2) = codeloc; *(unsigned short *)(closure->tramp + 6) = 0x4ef9; - if (cif->rtype->type == FFI_TYPE_STRUCT - && !cif->flags) + + if ( +#ifdef __MINT__ + (cif->rtype->type == FFI_TYPE_LONGDOUBLE) || +#endif + (((cif->rtype->type == FFI_TYPE_STRUCT) + && !cif->flags))) *(void **)(closure->tramp + 8) = ffi_closure_struct_SYSV; else *(void **)(closure->tramp + 8) = ffi_closure_SYSV; #ifdef __rtems__ rtems_cache_flush_multiple_data_lines( codeloc, FFI_TRAMPOLINE_SIZE ); +#elif defined(__MINT__) + Ssystem(S_FLUSHCACHE, codeloc, FFI_TRAMPOLINE_SIZE); #else syscall(SYS_cacheflush, codeloc, FLUSH_SCOPE_LINE, FLUSH_CACHE_BOTH, FFI_TRAMPOLINE_SIZE); @@ -286,4 +350,3 @@ ffi_prep_closure_loc (ffi_closure* closure, return FFI_OK; } - diff --git a/libffi/src/m68k/sysv.S b/libffi/src/m68k/sysv.S index dfdd864..f6f4ef9 100644 --- a/libffi/src/m68k/sysv.S +++ b/libffi/src/m68k/sysv.S @@ -1,6 +1,7 @@ /* ----------------------------------------------------------------------- - sysv.S - Copyright (c) 1998, 2012 Andreas Schwab + sysv.S - Copyright (c) 2012 Alan Hourihane + Copyright (c) 1998, 2012 Andreas Schwab Copyright (c) 2008 Red Hat, Inc. m68k Foreign Function Interface @@ -42,13 +43,19 @@ #define CFI_ENDPROC() #endif +#ifdef __MINT__ +#define CALLFUNC(funcname) _ ## funcname +#else +#define CALLFUNC(funcname) funcname +#endif + .text - .globl ffi_call_SYSV - .type ffi_call_SYSV,@function + .globl CALLFUNC(ffi_call_SYSV) + .type CALLFUNC(ffi_call_SYSV),@function .align 4 -ffi_call_SYSV: +CALLFUNC(ffi_call_SYSV): CFI_STARTPROC() link %fp,#0 CFI_OFFSET(14,-8) @@ -63,14 +70,18 @@ ffi_call_SYSV: move.l 8(%fp),-(%sp) pea 4(%sp) #if !defined __PIC__ - jsr ffi_prep_args + jsr CALLFUNC(ffi_prep_args) #else - bsr.l ffi_prep_args@PLTPC + bsr.l CALLFUNC(ffi_prep_args@PLTPC) #endif addq.l #8,%sp | Pass pointer to struct value, if any +#ifdef __MINT__ + move.l %d0,%a1 +#else move.l %a0,%a1 +#endif | Call the function move.l 24(%fp),%a0 @@ -142,7 +153,11 @@ retlongdouble: retpointer: btst #5,%d2 jbeq retstruct1 +#ifdef __MINT__ + move.l %d0,(%a1) +#else move.l %a0,(%a1) +#endif jbra epilogue retstruct1: @@ -162,13 +177,13 @@ epilogue: unlk %fp rts CFI_ENDPROC() - .size ffi_call_SYSV,.-ffi_call_SYSV + .size CALLFUNC(ffi_call_SYSV),.-CALLFUNC(ffi_call_SYSV) - .globl ffi_closure_SYSV - .type ffi_closure_SYSV, @function + .globl CALLFUNC(ffi_closure_SYSV) + .type CALLFUNC(ffi_closure_SYSV), @function .align 4 -ffi_closure_SYSV: +CALLFUNC(ffi_closure_SYSV): CFI_STARTPROC() link %fp,#-12 CFI_OFFSET(14,-8) @@ -178,9 +193,9 @@ ffi_closure_SYSV: pea -12(%fp) move.l %a0,-(%sp) #if !defined __PIC__ - jsr ffi_closure_SYSV_inner + jsr CALLFUNC(ffi_closure_SYSV_inner) #else - bsr.l ffi_closure_SYSV_inner@PLTPC + bsr.l CALLFUNC(ffi_closure_SYSV_inner@PLTPC) #endif lsr.l #1,%d0 @@ -240,13 +255,13 @@ ffi_closure_SYSV: jra .Lcls_epilogue CFI_ENDPROC() - .size ffi_closure_SYSV,.-ffi_closure_SYSV + .size CALLFUNC(ffi_closure_SYSV),.-CALLFUNC(ffi_closure_SYSV) - .globl ffi_closure_struct_SYSV - .type ffi_closure_struct_SYSV, @function + .globl CALLFUNC(ffi_closure_struct_SYSV) + .type CALLFUNC(ffi_closure_struct_SYSV), @function .align 4 -ffi_closure_struct_SYSV: +CALLFUNC(ffi_closure_struct_SYSV): CFI_STARTPROC() link %fp,#0 CFI_OFFSET(14,-8) @@ -256,14 +271,14 @@ ffi_closure_struct_SYSV: move.l %a1,-(%sp) move.l %a0,-(%sp) #if !defined __PIC__ - jsr ffi_closure_SYSV_inner + jsr CALLFUNC(ffi_closure_SYSV_inner) #else - bsr.l ffi_closure_SYSV_inner@PLTPC + bsr.l CALLFUNC(ffi_closure_SYSV_inner@PLTPC) #endif unlk %fp rts CFI_ENDPROC() - .size ffi_closure_struct_SYSV,.-ffi_closure_struct_SYSV + .size CALLFUNC(ffi_closure_struct_SYSV),.-CALLFUNC(ffi_closure_struct_SYSV) #if defined __ELF__ && defined __linux__ .section .note.GNU-stack,"",@progbits diff --git a/libffi/src/powerpc/ffi_darwin.c b/libffi/src/powerpc/ffi_darwin.c index ee03dab..dd897f4 100644 --- a/libffi/src/powerpc/ffi_darwin.c +++ b/libffi/src/powerpc/ffi_darwin.c @@ -1065,10 +1065,10 @@ ffi_prep_closure_loc (ffi_closure* closure, closure->cif = cif; closure->fun = fun; closure->user_data = user_data; + break; default: - - FFI_ASSERT(0); + return FFI_BAD_ABI; break; } return FFI_OK; @@ -1235,7 +1235,7 @@ ffi_closure_helper_DARWIN (ffi_closure *closure, void *rvalue, if (arg_types[i]->elements[0]->type == FFI_TYPE_DOUBLE) size_al = ALIGN(arg_types[i]->size, 8); # if defined(POWERPC64) - FFI_ASSERT (cif->abi != FFI_DARWIN) + FFI_ASSERT (cif->abi != FFI_DARWIN); avalue[i] = pgr; pgr += (size_al + 7) / 8; # else diff --git a/libffi/src/prep_cif.c b/libffi/src/prep_cif.c index eb68341..5d1924b 100644 --- a/libffi/src/prep_cif.c +++ b/libffi/src/prep_cif.c @@ -140,6 +140,9 @@ ffi_status FFI_HIDDEN ffi_prep_cif_core(ffi_cif *cif, ffi_abi abi, #ifdef SPARC && (cif->abi != FFI_V9 || cif->rtype->size > 32) #endif +#ifdef TILE + && (cif->rtype->size > 10 * FFI_SIZEOF_ARG) +#endif ) bytes = STACK_ARG_SIZE(sizeof(void*)); #endif @@ -169,6 +172,16 @@ ffi_status FFI_HIDDEN ffi_prep_cif_core(ffi_cif *cif, ffi_abi abi, if (((*ptr)->alignment - 1) & bytes) bytes = ALIGN(bytes, (*ptr)->alignment); +#ifdef TILE + if (bytes < 10 * FFI_SIZEOF_ARG && + bytes + STACK_ARG_SIZE((*ptr)->size) > 10 * FFI_SIZEOF_ARG) + { + /* An argument is never split between the 10 parameter + registers and the stack. */ + bytes = 10 * FFI_SIZEOF_ARG; + } +#endif + bytes += STACK_ARG_SIZE((*ptr)->size); } #endif diff --git a/libffi/src/tile/ffi.c b/libffi/src/tile/ffi.c new file mode 100644 index 0000000..3a94469 --- /dev/null +++ b/libffi/src/tile/ffi.c @@ -0,0 +1,355 @@ +/* ----------------------------------------------------------------------- + ffi.c - Copyright (c) 2012 Tilera Corp. + + TILE Foreign Function Interface + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + ----------------------------------------------------------------------- */ + +#include +#include +#include +#include +#include +#include +#include +#include + + +/* The first 10 registers are used to pass arguments and return values. */ +#define NUM_ARG_REGS 10 + +/* Performs a raw function call with the given NUM_ARG_REGS register arguments + and the specified additional stack arguments (if any). */ +extern void ffi_call_tile(ffi_sarg reg_args[NUM_ARG_REGS], + const ffi_sarg *stack_args, + size_t stack_args_bytes, + void (*fnaddr)(void)) + FFI_HIDDEN; + +/* This handles the raw call from the closure stub, cleaning up the + parameters and delegating to ffi_closure_tile_inner. */ +extern void ffi_closure_tile(void) FFI_HIDDEN; + + +ffi_status +ffi_prep_cif_machdep(ffi_cif *cif) +{ + /* We always allocate room for all registers. Even if we don't + use them as parameters, they get returned in the same array + as struct return values so we need to make room. */ + if (cif->bytes < NUM_ARG_REGS * FFI_SIZEOF_ARG) + cif->bytes = NUM_ARG_REGS * FFI_SIZEOF_ARG; + + if (cif->rtype->size > NUM_ARG_REGS * FFI_SIZEOF_ARG) + cif->flags = FFI_TYPE_STRUCT; + else + cif->flags = FFI_TYPE_INT; + + /* Nothing to do. */ + return FFI_OK; +} + + +static long +assign_to_ffi_arg(ffi_sarg *out, void *in, const ffi_type *type, + int write_to_reg) +{ + switch (type->type) + { + case FFI_TYPE_SINT8: + *out = *(SINT8 *)in; + return 1; + + case FFI_TYPE_UINT8: + *out = *(UINT8 *)in; + return 1; + + case FFI_TYPE_SINT16: + *out = *(SINT16 *)in; + return 1; + + case FFI_TYPE_UINT16: + *out = *(UINT16 *)in; + return 1; + + case FFI_TYPE_SINT32: + case FFI_TYPE_UINT32: +#ifndef __LP64__ + case FFI_TYPE_POINTER: +#endif + /* Note that even unsigned 32-bit quantities are sign extended + on tilegx when stored in a register. */ + *out = *(SINT32 *)in; + return 1; + + case FFI_TYPE_FLOAT: +#ifdef __tilegx__ + if (write_to_reg) + { + /* Properly sign extend the value. */ + union { float f; SINT32 s32; } val; + val.f = *(float *)in; + *out = val.s32; + } + else +#endif + { + *(float *)out = *(float *)in; + } + return 1; + + case FFI_TYPE_SINT64: + case FFI_TYPE_UINT64: + case FFI_TYPE_DOUBLE: +#ifdef __LP64__ + case FFI_TYPE_POINTER: +#endif + *(UINT64 *)out = *(UINT64 *)in; + return sizeof(UINT64) / FFI_SIZEOF_ARG; + + case FFI_TYPE_STRUCT: + memcpy(out, in, type->size); + return (type->size + FFI_SIZEOF_ARG - 1) / FFI_SIZEOF_ARG; + + case FFI_TYPE_VOID: + /* Must be a return type. Nothing to do. */ + return 0; + + default: + FFI_ASSERT(0); + return -1; + } +} + + +void +ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) +{ + ffi_sarg * const arg_mem = alloca(cif->bytes); + ffi_sarg * const reg_args = arg_mem; + ffi_sarg * const stack_args = ®_args[NUM_ARG_REGS]; + ffi_sarg *argp = arg_mem; + ffi_type ** const arg_types = cif->arg_types; + const long num_args = cif->nargs; + long i; + + if (cif->flags == FFI_TYPE_STRUCT) + { + /* Pass a hidden pointer to the return value. We make sure there + is scratch space for the callee to store the return value even if + our caller doesn't care about it. */ + *argp++ = (intptr_t)(rvalue ? rvalue : alloca(cif->rtype->size)); + + /* No more work needed to return anything. */ + rvalue = NULL; + } + + for (i = 0; i < num_args; i++) + { + ffi_type *type = arg_types[i]; + void * const arg_in = avalue[i]; + ptrdiff_t arg_word = argp - arg_mem; + +#ifndef __tilegx__ + /* Doubleword-aligned values are always in an even-number register + pair, or doubleword-aligned stack slot if out of registers. */ + long align = arg_word & (type->alignment > FFI_SIZEOF_ARG); + argp += align; + arg_word += align; +#endif + + if (type->type == FFI_TYPE_STRUCT) + { + const size_t arg_size_in_words = + (type->size + FFI_SIZEOF_ARG - 1) / FFI_SIZEOF_ARG; + + if (arg_word < NUM_ARG_REGS && + arg_word + arg_size_in_words > NUM_ARG_REGS) + { + /* Args are not allowed to span registers and the stack. */ + argp = stack_args; + } + + memcpy(argp, arg_in, type->size); + argp += arg_size_in_words; + } + else + { + argp += assign_to_ffi_arg(argp, arg_in, arg_types[i], 1); + } + } + + /* Actually do the call. */ + ffi_call_tile(reg_args, stack_args, + cif->bytes - (NUM_ARG_REGS * FFI_SIZEOF_ARG), fn); + + if (rvalue != NULL) + assign_to_ffi_arg(rvalue, reg_args, cif->rtype, 0); +} + + +/* Template code for closure. */ +extern const UINT64 ffi_template_tramp_tile[] FFI_HIDDEN; + + +ffi_status +ffi_prep_closure_loc (ffi_closure *closure, + ffi_cif *cif, + void (*fun)(ffi_cif*, void*, void**, void*), + void *user_data, + void *codeloc) +{ +#ifdef __tilegx__ + /* TILE-Gx */ + SINT64 c; + SINT64 h; + int s; + UINT64 *out; + + if (cif->abi != FFI_UNIX) + return FFI_BAD_ABI; + + out = (UINT64 *)closure->tramp; + + c = (intptr_t)closure; + h = (intptr_t)ffi_closure_tile; + s = 0; + + /* Find the smallest shift count that doesn't lose information + (i.e. no need to explicitly insert high bits of the address that + are just the sign extension of the low bits). */ + while ((c >> s) != (SINT16)(c >> s) || (h >> s) != (SINT16)(h >> s)) + s += 16; + +#define OPS(a, b, shift) \ + (create_Imm16_X0((a) >> (shift)) | create_Imm16_X1((b) >> (shift))) + + /* Emit the moveli. */ + *out++ = ffi_template_tramp_tile[0] | OPS(c, h, s); + for (s -= 16; s >= 0; s -= 16) + *out++ = ffi_template_tramp_tile[1] | OPS(c, h, s); + +#undef OPS + + *out++ = ffi_template_tramp_tile[2]; + +#else + /* TILEPro */ + UINT64 *out; + intptr_t delta; + + if (cif->abi != FFI_UNIX) + return FFI_BAD_ABI; + + out = (UINT64 *)closure->tramp; + delta = (intptr_t)ffi_closure_tile - (intptr_t)codeloc; + + *out++ = ffi_template_tramp_tile[0] | create_JOffLong_X1(delta >> 3); +#endif + + closure->cif = cif; + closure->fun = fun; + closure->user_data = user_data; + + invalidate_icache(closure->tramp, (char *)out - closure->tramp, + getpagesize()); + + return FFI_OK; +} + + +/* This is called by the assembly wrapper for closures. This does + all of the work. On entry reg_args[0] holds the values the registers + had when the closure was invoked. On return reg_args[1] holds the register + values to be returned to the caller (many of which may be garbage). */ +void FFI_HIDDEN +ffi_closure_tile_inner(ffi_closure *closure, + ffi_sarg reg_args[2][NUM_ARG_REGS], + ffi_sarg *stack_args) +{ + ffi_cif * const cif = closure->cif; + void ** const avalue = alloca(cif->nargs * sizeof(void *)); + void *rvalue; + ffi_type ** const arg_types = cif->arg_types; + ffi_sarg * const reg_args_in = reg_args[0]; + ffi_sarg * const reg_args_out = reg_args[1]; + ffi_sarg * argp; + long i, arg_word, nargs = cif->nargs; + /* Use a union to guarantee proper alignment for double. */ + union { ffi_sarg arg[NUM_ARG_REGS]; double d; UINT64 u64; } closure_ret; + + /* Start out reading register arguments. */ + argp = reg_args_in; + + /* Copy the caller's structure return address to that the closure + returns the data directly to the caller. */ + if (cif->flags == FFI_TYPE_STRUCT) + { + /* Return by reference via hidden pointer. */ + rvalue = (void *)(intptr_t)*argp++; + arg_word = 1; + } + else + { + /* Return the value in registers. */ + rvalue = &closure_ret; + arg_word = 0; + } + + /* Grab the addresses of the arguments. */ + for (i = 0; i < nargs; i++) + { + ffi_type * const type = arg_types[i]; + const size_t arg_size_in_words = + (type->size + FFI_SIZEOF_ARG - 1) / FFI_SIZEOF_ARG; + +#ifndef __tilegx__ + /* Doubleword-aligned values are always in an even-number register + pair, or doubleword-aligned stack slot if out of registers. */ + long align = arg_word & (type->alignment > FFI_SIZEOF_ARG); + argp += align; + arg_word += align; +#endif + + if (arg_word == NUM_ARG_REGS || + (arg_word < NUM_ARG_REGS && + arg_word + arg_size_in_words > NUM_ARG_REGS)) + { + /* Switch to reading arguments from the stack. */ + argp = stack_args; + arg_word = NUM_ARG_REGS; + } + + avalue[i] = argp; + argp += arg_size_in_words; + arg_word += arg_size_in_words; + } + + /* Invoke the closure. */ + closure->fun(cif, rvalue, avalue, closure->user_data); + + if (cif->flags != FFI_TYPE_STRUCT) + { + /* Canonicalize for register representation. */ + assign_to_ffi_arg(reg_args_out, &closure_ret, cif->rtype, 1); + } +} diff --git a/libffi/src/tile/ffitarget.h b/libffi/src/tile/ffitarget.h new file mode 100644 index 0000000..679fb5d --- /dev/null +++ b/libffi/src/tile/ffitarget.h @@ -0,0 +1,65 @@ +/* -----------------------------------------------------------------*-C-*- + ffitarget.h - Copyright (c) 2012 Tilera Corp. + Target configuration macros for TILE. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + ----------------------------------------------------------------------- */ + +#ifndef LIBFFI_TARGET_H +#define LIBFFI_TARGET_H + +#ifndef LIBFFI_H +#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." +#endif + +#ifndef LIBFFI_ASM + +#include + +typedef uint_reg_t ffi_arg; +typedef int_reg_t ffi_sarg; + +typedef enum ffi_abi { + FFI_FIRST_ABI = 0, + FFI_UNIX, + FFI_LAST_ABI, + FFI_DEFAULT_ABI = FFI_UNIX +} ffi_abi; +#endif + +/* ---- Definitions for closures ----------------------------------------- */ +#define FFI_CLOSURES 1 + +#ifdef __tilegx__ +/* We always pass 8-byte values, even in -m32 mode. */ +# define FFI_SIZEOF_ARG 8 +# ifdef __LP64__ +# define FFI_TRAMPOLINE_SIZE (8 * 5) /* 5 bundles */ +# else +# define FFI_TRAMPOLINE_SIZE (8 * 3) /* 3 bundles */ +# endif +#else +# define FFI_SIZEOF_ARG 4 +# define FFI_TRAMPOLINE_SIZE 8 /* 1 bundle */ +#endif +#define FFI_NATIVE_RAW_API 0 + +#endif diff --git a/libffi/src/tile/tile.S b/libffi/src/tile/tile.S new file mode 100644 index 0000000..a186e1f --- /dev/null +++ b/libffi/src/tile/tile.S @@ -0,0 +1,360 @@ +/* ----------------------------------------------------------------------- + tile.S - Copyright (c) 2011 Tilera Corp. + + Tilera TILEPro and TILE-Gx Foreign Function Interface + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + ----------------------------------------------------------------------- */ + +#define LIBFFI_ASM +#include +#include + +/* Number of bytes in a register. */ +#define REG_SIZE FFI_SIZEOF_ARG + +/* Number of bytes in stack linkage area for backtracing. + + A note about the ABI: on entry to a procedure, sp points to a stack + slot where it must spill the return address if it's not a leaf. + REG_SIZE bytes beyond that is a slot owned by the caller which + contains the sp value that the caller had when it was originally + entered (i.e. the caller's frame pointer). */ +#define LINKAGE_SIZE (2 * REG_SIZE) + +/* The first 10 registers are used to pass arguments and return values. */ +#define NUM_ARG_REGS 10 + +#ifdef __tilegx__ +#define SW st +#define LW ld +#define BGZT bgtzt +#else +#define SW sw +#define LW lw +#define BGZT bgzt +#endif + + +/* void ffi_call_tile (int_reg_t reg_args[NUM_ARG_REGS], + const int_reg_t *stack_args, + unsigned long stack_args_bytes, + void (*fnaddr)(void)); + + On entry, REG_ARGS contain the outgoing register values, + and STACK_ARGS containts STACK_ARG_BYTES of additional values + to be passed on the stack. If STACK_ARG_BYTES is zero, then + STACK_ARGS is ignored. + + When the invoked function returns, the values of r0-r9 are + blindly stored back into REG_ARGS for the caller to examine. */ + + .section .text.ffi_call_tile, "ax", @progbits + .align 8 + .globl ffi_call_tile + FFI_HIDDEN(ffi_call_tile) +ffi_call_tile: + +/* Incoming arguments. */ +#define REG_ARGS r0 +#define INCOMING_STACK_ARGS r1 +#define STACK_ARG_BYTES r2 +#define ORIG_FNADDR r3 + +/* Temporary values. */ +#define FRAME_SIZE r10 +#define TMP r11 +#define TMP2 r12 +#define OUTGOING_STACK_ARGS r13 +#define REG_ADDR_PTR r14 +#define RETURN_REG_ADDR r15 +#define FNADDR r16 + + .cfi_startproc + { + /* Save return address. */ + SW sp, lr + .cfi_offset lr, 0 + /* Prepare to spill incoming r52. */ + addi TMP, sp, -REG_SIZE + /* Increase frame size to have room to spill r52 and REG_ARGS. + The +7 is to round up mod 8. */ + addi FRAME_SIZE, STACK_ARG_BYTES, \ + REG_SIZE + REG_SIZE + LINKAGE_SIZE + 7 + } + { + /* Round stack frame size to a multiple of 8 to satisfy ABI. */ + andi FRAME_SIZE, FRAME_SIZE, -8 + /* Compute where to spill REG_ARGS value. */ + addi TMP2, sp, -(REG_SIZE * 2) + } + { + /* Spill incoming r52. */ + SW TMP, r52 + .cfi_offset r52, -REG_SIZE + /* Set up our frame pointer. */ + move r52, sp + .cfi_def_cfa_register r52 + /* Push stack frame. */ + sub sp, sp, FRAME_SIZE + } + { + /* Prepare to set up stack linkage. */ + addi TMP, sp, REG_SIZE + /* Prepare to memcpy stack args. */ + addi OUTGOING_STACK_ARGS, sp, LINKAGE_SIZE + /* Save REG_ARGS which we will need after we call the subroutine. */ + SW TMP2, REG_ARGS + } + { + /* Set up linkage info to hold incoming stack pointer. */ + SW TMP, r52 + } + { + /* Skip stack args memcpy if we don't have any stack args (common). */ + blezt STACK_ARG_BYTES, .Ldone_stack_args_memcpy + } + +.Lmemcpy_stack_args: + { + /* Load incoming argument from stack_args. */ + LW TMP, INCOMING_STACK_ARGS + addi INCOMING_STACK_ARGS, INCOMING_STACK_ARGS, REG_SIZE + } + { + /* Store stack argument into outgoing stack argument area. */ + SW OUTGOING_STACK_ARGS, TMP + addi OUTGOING_STACK_ARGS, OUTGOING_STACK_ARGS, REG_SIZE + addi STACK_ARG_BYTES, STACK_ARG_BYTES, -REG_SIZE + } + { + BGZT STACK_ARG_BYTES, .Lmemcpy_stack_args + } +.Ldone_stack_args_memcpy: + + { + /* Copy aside ORIG_FNADDR so we can overwrite its register. */ + move FNADDR, ORIG_FNADDR + /* Prepare to load argument registers. */ + addi REG_ADDR_PTR, r0, REG_SIZE + /* Load outgoing r0. */ + LW r0, r0 + } + + /* Load up argument registers from the REG_ARGS array. */ +#define LOAD_REG(REG, PTR) \ + { \ + LW REG, PTR ; \ + addi PTR, PTR, REG_SIZE \ + } + + LOAD_REG(r1, REG_ADDR_PTR) + LOAD_REG(r2, REG_ADDR_PTR) + LOAD_REG(r3, REG_ADDR_PTR) + LOAD_REG(r4, REG_ADDR_PTR) + LOAD_REG(r5, REG_ADDR_PTR) + LOAD_REG(r6, REG_ADDR_PTR) + LOAD_REG(r7, REG_ADDR_PTR) + LOAD_REG(r8, REG_ADDR_PTR) + LOAD_REG(r9, REG_ADDR_PTR) + + { + /* Call the subroutine. */ + jalr FNADDR + } + + { + /* Restore original lr. */ + LW lr, r52 + /* Prepare to recover ARGS, which we spilled earlier. */ + addi TMP, r52, -(2 * REG_SIZE) + } + { + /* Restore ARGS, so we can fill it in with the return regs r0-r9. */ + LW RETURN_REG_ADDR, TMP + /* Prepare to restore original r52. */ + addi TMP, r52, -REG_SIZE + } + + { + /* Pop stack frame. */ + move sp, r52 + /* Restore original r52. */ + LW r52, TMP + } + +#define STORE_REG(REG, PTR) \ + { \ + SW PTR, REG ; \ + addi PTR, PTR, REG_SIZE \ + } + + /* Return all register values by reference. */ + STORE_REG(r0, RETURN_REG_ADDR) + STORE_REG(r1, RETURN_REG_ADDR) + STORE_REG(r2, RETURN_REG_ADDR) + STORE_REG(r3, RETURN_REG_ADDR) + STORE_REG(r4, RETURN_REG_ADDR) + STORE_REG(r5, RETURN_REG_ADDR) + STORE_REG(r6, RETURN_REG_ADDR) + STORE_REG(r7, RETURN_REG_ADDR) + STORE_REG(r8, RETURN_REG_ADDR) + STORE_REG(r9, RETURN_REG_ADDR) + + { + jrp lr + } + + .cfi_endproc + .size ffi_call_tile, .-ffi_call_tile + +/* ffi_closure_tile(...) + + On entry, lr points to the closure plus 8 bytes, and r10 + contains the actual return address. + + This function simply dumps all register parameters into a stack array + and passes the closure, the registers array, and the stack arguments + to C code that does all of the actual closure processing. */ + + .section .text.ffi_closure_tile, "ax", @progbits + .align 8 + .globl ffi_closure_tile + FFI_HIDDEN(ffi_closure_tile) + + .cfi_startproc +/* Room to spill all NUM_ARG_REGS incoming registers, plus frame linkage. */ +#define CLOSURE_FRAME_SIZE (((NUM_ARG_REGS * REG_SIZE * 2 + LINKAGE_SIZE) + 7) & -8) +ffi_closure_tile: + { +#ifdef __tilegx__ + st sp, lr + .cfi_offset lr, 0 +#else + /* Save return address (in r10 due to closure stub wrapper). */ + SW sp, r10 + .cfi_return_column r10 + .cfi_offset r10, 0 +#endif + /* Compute address for stack frame linkage. */ + addli r10, sp, -(CLOSURE_FRAME_SIZE - REG_SIZE) + } + { + /* Save incoming stack pointer in linkage area. */ + SW r10, sp + .cfi_offset sp, -(CLOSURE_FRAME_SIZE - REG_SIZE) + /* Push a new stack frame. */ + addli sp, sp, -CLOSURE_FRAME_SIZE + .cfi_adjust_cfa_offset CLOSURE_FRAME_SIZE + } + + { + /* Create pointer to where to start spilling registers. */ + addi r10, sp, LINKAGE_SIZE + } + + /* Spill all the incoming registers. */ + STORE_REG(r0, r10) + STORE_REG(r1, r10) + STORE_REG(r2, r10) + STORE_REG(r3, r10) + STORE_REG(r4, r10) + STORE_REG(r5, r10) + STORE_REG(r6, r10) + STORE_REG(r7, r10) + STORE_REG(r8, r10) + { + /* Save r9. */ + SW r10, r9 +#ifdef __tilegx__ + /* Pointer to closure is passed in r11. */ + move r0, r11 +#else + /* Compute pointer to the closure object. Because the closure + starts with a "jal ffi_closure_tile", we can just take the + value of lr (a phony return address pointing into the closure) + and subtract 8. */ + addi r0, lr, -8 +#endif + /* Compute a pointer to the register arguments we just spilled. */ + addi r1, sp, LINKAGE_SIZE + } + { + /* Compute a pointer to the extra stack arguments (if any). */ + addli r2, sp, CLOSURE_FRAME_SIZE + LINKAGE_SIZE + /* Call C code to deal with all of the grotty details. */ + jal ffi_closure_tile_inner + } + { + addli r10, sp, CLOSURE_FRAME_SIZE + } + { + /* Restore the return address. */ + LW lr, r10 + /* Compute pointer to registers array. */ + addli r10, sp, LINKAGE_SIZE + (NUM_ARG_REGS * REG_SIZE) + } + /* Return all the register values, which C code may have set. */ + LOAD_REG(r0, r10) + LOAD_REG(r1, r10) + LOAD_REG(r2, r10) + LOAD_REG(r3, r10) + LOAD_REG(r4, r10) + LOAD_REG(r5, r10) + LOAD_REG(r6, r10) + LOAD_REG(r7, r10) + LOAD_REG(r8, r10) + LOAD_REG(r9, r10) + { + /* Pop the frame. */ + addli sp, sp, CLOSURE_FRAME_SIZE + jrp lr + } + + .cfi_endproc + .size ffi_closure_tile, . - ffi_closure_tile + + +/* What follows are code template instructions that get copied to the + closure trampoline by ffi_prep_closure_loc. The zeroed operands + get replaced by their proper values at runtime. */ + + .section .text.ffi_template_tramp_tile, "ax", @progbits + .align 8 + .globl ffi_template_tramp_tile + FFI_HIDDEN(ffi_template_tramp_tile) +ffi_template_tramp_tile: +#ifdef __tilegx__ + { + moveli r11, 0 /* backpatched to address of containing closure. */ + moveli r10, 0 /* backpatched to ffi_closure_tile. */ + } + /* Note: the following bundle gets generated multiple times + depending on the pointer value (esp. useful for -m32 mode). */ + { shl16insli r11, r11, 0 ; shl16insli r10, r10, 0 } + { info 2+8 /* for backtracer: -> pc in lr, frame size 0 */ ; jr r10 } +#else + /* 'jal .' yields a PC-relative offset of zero so we can OR in the + right offset at runtime. */ + { move r10, lr ; jal . /* ffi_closure_tile */ } +#endif + + .size ffi_template_tramp_tile, . - ffi_template_tramp_tile diff --git a/libffi/src/x86/ffi.c b/libffi/src/x86/ffi.c index f643b34..611e221 100644 --- a/libffi/src/x86/ffi.c +++ b/libffi/src/x86/ffi.c @@ -58,7 +58,8 @@ void ffi_prep_args(char *stack, extended_cif *ecif) argp = stack; - if (ecif->cif->flags == FFI_TYPE_STRUCT + if ((ecif->cif->flags == FFI_TYPE_STRUCT + || ecif->cif->flags == FFI_TYPE_MS_STRUCT) #ifdef X86_WIN64 && (ecif->cif->rtype->size != 1 && ecif->cif->rtype->size != 2 && ecif->cif->rtype->size != 4 && ecif->cif->rtype->size != 8) @@ -279,7 +280,12 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) else #endif { - cif->flags = FFI_TYPE_STRUCT; +#ifdef X86_WIN32 + if (cif->abi == FFI_MS_CDECL) + cif->flags = FFI_TYPE_MS_STRUCT; + else +#endif + cif->flags = FFI_TYPE_STRUCT; /* allocate space for return value pointer */ cif->bytes += ALIGN(sizeof(void*), FFI_SIZEOF_ARG); } @@ -349,7 +355,8 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) } #else if (rvalue == NULL - && cif->flags == FFI_TYPE_STRUCT) + && (cif->flags == FFI_TYPE_STRUCT + || cif->flags == FFI_TYPE_MS_STRUCT)) { ecif.rvalue = alloca(cif->rtype->size); } @@ -368,6 +375,7 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) #elif defined(X86_WIN32) case FFI_SYSV: case FFI_STDCALL: + case FFI_MS_CDECL: ffi_call_win32(ffi_prep_args, &ecif, cif->abi, cif->bytes, cif->flags, ecif.rvalue, fn); break; @@ -513,7 +521,8 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue, argp += sizeof(void *); } #else - if ( cif->flags == FFI_TYPE_STRUCT ) { + if ( cif->flags == FFI_TYPE_STRUCT + || cif->flags == FFI_TYPE_MS_STRUCT ) { *rvalue = *(void **) argp; argp += sizeof(void *); } @@ -673,6 +682,12 @@ ffi_prep_closure_loc (ffi_closure* closure, &ffi_closure_STDCALL, (void*)codeloc, cif->bytes); } + else if (cif->abi == FFI_MS_CDECL) + { + FFI_INIT_TRAMPOLINE (&closure->tramp[0], + &ffi_closure_SYSV, + (void*)codeloc); + } #endif /* X86_WIN32 */ #endif /* !X86_WIN64 */ else @@ -762,8 +777,9 @@ ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue) /* If the return value is a struct and we don't have a return */ /* value address then we need to make one */ - if ((rvalue == NULL) && - (cif->rtype->type == FFI_TYPE_STRUCT)) + if (rvalue == NULL + && (cif->flags == FFI_TYPE_STRUCT + || cif->flags == FFI_TYPE_MS_STRUCT)) { ecif.rvalue = alloca(cif->rtype->size); } @@ -776,6 +792,7 @@ ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue) #ifdef X86_WIN32 case FFI_SYSV: case FFI_STDCALL: + case FFI_MS_CDECL: ffi_call_win32(ffi_prep_args_raw, &ecif, cif->abi, cif->bytes, cif->flags, ecif.rvalue, fn); break; diff --git a/libffi/src/x86/ffi64.c b/libffi/src/x86/ffi64.c index defd774..1daa1c0 100644 --- a/libffi/src/x86/ffi64.c +++ b/libffi/src/x86/ffi64.c @@ -37,11 +37,17 @@ #define MAX_GPR_REGS 6 #define MAX_SSE_REGS 8 +#ifdef __INTEL_COMPILER +#define UINT128 __m128 +#else +#define UINT128 __int128_t +#endif + struct register_args { /* Registers for argument passing. */ UINT64 gpr[MAX_GPR_REGS]; - __int128_t sse[MAX_SSE_REGS]; + UINT128 sse[MAX_SSE_REGS]; }; extern void ffi_call_unix64 (void *args, unsigned long bytes, unsigned flags, diff --git a/libffi/src/x86/ffitarget.h b/libffi/src/x86/ffitarget.h index fc01541..46f294c 100644 --- a/libffi/src/x86/ffitarget.h +++ b/libffi/src/x86/ffitarget.h @@ -81,9 +81,13 @@ typedef enum ffi_abi { FFI_STDCALL, FFI_THISCALL, FFI_FASTCALL, + FFI_MS_CDECL, FFI_LAST_ABI, - /* TODO: Add fastcall support for the sake of completeness */ +#ifdef _MSC_VER + FFI_DEFAULT_ABI = FFI_MS_CDECL +#else FFI_DEFAULT_ABI = FFI_SYSV +#endif #elif defined(X86_WIN64) FFI_WIN64, @@ -110,6 +114,7 @@ typedef enum ffi_abi { #define FFI_TYPE_SMALL_STRUCT_1B (FFI_TYPE_LAST + 1) #define FFI_TYPE_SMALL_STRUCT_2B (FFI_TYPE_LAST + 2) #define FFI_TYPE_SMALL_STRUCT_4B (FFI_TYPE_LAST + 3) +#define FFI_TYPE_MS_STRUCT (FFI_TYPE_LAST + 4) #if defined (X86_64) || (defined (__x86_64__) && defined (X86_DARWIN)) #define FFI_TRAMPOLINE_SIZE 24 diff --git a/libffi/src/x86/win32.S b/libffi/src/x86/win32.S index deb4a03..24b7bbd 100644 --- a/libffi/src/x86/win32.S +++ b/libffi/src/x86/win32.S @@ -108,31 +108,37 @@ ca_jumpdata: dd offset ca_retfloat ;; FFI_TYPE_FLOAT dd offset ca_retdouble ;; FFI_TYPE_DOUBLE dd offset ca_retlongdouble ;; FFI_TYPE_LONGDOUBLE - dd offset ca_retint8 ;; FFI_TYPE_UINT8 - dd offset ca_retint8 ;; FFI_TYPE_SINT8 - dd offset ca_retint16 ;; FFI_TYPE_UINT16 - dd offset ca_retint16 ;; FFI_TYPE_SINT16 + dd offset ca_retuint8 ;; FFI_TYPE_UINT8 + dd offset ca_retsint8 ;; FFI_TYPE_SINT8 + dd offset ca_retuint16 ;; FFI_TYPE_UINT16 + dd offset ca_retsint16 ;; FFI_TYPE_SINT16 dd offset ca_retint ;; FFI_TYPE_UINT32 dd offset ca_retint ;; FFI_TYPE_SINT32 dd offset ca_retint64 ;; FFI_TYPE_UINT64 dd offset ca_retint64 ;; FFI_TYPE_SINT64 dd offset ca_epilogue ;; FFI_TYPE_STRUCT dd offset ca_retint ;; FFI_TYPE_POINTER - dd offset ca_retint8 ;; FFI_TYPE_SMALL_STRUCT_1B - dd offset ca_retint16 ;; FFI_TYPE_SMALL_STRUCT_2B + dd offset ca_retstruct1b ;; FFI_TYPE_SMALL_STRUCT_1B + dd offset ca_retstruct2b ;; FFI_TYPE_SMALL_STRUCT_2B dd offset ca_retint ;; FFI_TYPE_SMALL_STRUCT_4B + dd offset ca_epilogue ;; FFI_TYPE_MS_STRUCT -ca_retint8: - ;; Load %ecx with the pointer to storage for the return value - mov ecx, rvalue - mov [ecx + 0], al - jmp ca_epilogue + /* Sign/zero extend as appropriate. */ +ca_retuint8: + movzx eax, al + jmp ca_retint -ca_retint16: - ;; Load %ecx with the pointer to storage for the return value - mov ecx, rvalue - mov [ecx + 0], ax - jmp ca_epilogue +ca_retsint8: + movsx eax, al + jmp ca_retint + +ca_retuint16: + movzx eax, ax + jmp ca_retint + +ca_retsint16: + movsx eax, ax + jmp ca_retint ca_retint: ;; Load %ecx with the pointer to storage for the return value @@ -165,14 +171,24 @@ ca_retlongdouble: fstp TBYTE PTR [ecx] jmp ca_epilogue +ca_retstruct1b: + ;; Load %ecx with the pointer to storage for the return value + mov ecx, rvalue + mov [ecx + 0], al + jmp ca_epilogue + +ca_retstruct2b: + ;; Load %ecx with the pointer to storage for the return value + mov ecx, rvalue + mov [ecx + 0], ax + jmp ca_epilogue + ca_epilogue: ;; Epilogue code is autogenerated. ret ffi_call_win32 ENDP ffi_closure_THISCALL PROC NEAR FORCEFRAME - push ebp - mov ebp, esp sub esp, 40 lea edx, [ebp -24] mov [ebp - 12], edx /* resp */ @@ -187,7 +203,7 @@ ffi_closure_SYSV PROC NEAR FORCEFRAME lea edx, [ebp - 24] mov [ebp - 12], edx ;; resp lea edx, [ebp + 8] -stub: +stub:: mov [esp + 8], edx ;; args lea edx, [ebp - 12] mov [esp + 4], edx ;; &resp @@ -204,26 +220,35 @@ cs_jumpdata: dd offset cs_retfloat ;; FFI_TYPE_FLOAT dd offset cs_retdouble ;; FFI_TYPE_DOUBLE dd offset cs_retlongdouble ;; FFI_TYPE_LONGDOUBLE - dd offset cs_retint8 ;; FFI_TYPE_UINT8 - dd offset cs_retint8 ;; FFI_TYPE_SINT8 - dd offset cs_retint16 ;; FFI_TYPE_UINT16 - dd offset cs_retint16 ;; FFI_TYPE_SINT16 + dd offset cs_retuint8 ;; FFI_TYPE_UINT8 + dd offset cs_retsint8 ;; FFI_TYPE_SINT8 + dd offset cs_retuint16 ;; FFI_TYPE_UINT16 + dd offset cs_retsint16 ;; FFI_TYPE_SINT16 dd offset cs_retint ;; FFI_TYPE_UINT32 dd offset cs_retint ;; FFI_TYPE_SINT32 dd offset cs_retint64 ;; FFI_TYPE_UINT64 dd offset cs_retint64 ;; FFI_TYPE_SINT64 dd offset cs_retstruct ;; FFI_TYPE_STRUCT dd offset cs_retint ;; FFI_TYPE_POINTER - dd offset cs_retint8 ;; FFI_TYPE_SMALL_STRUCT_1B - dd offset cs_retint16 ;; FFI_TYPE_SMALL_STRUCT_2B + dd offset cs_retsint8 ;; FFI_TYPE_SMALL_STRUCT_1B + dd offset cs_retsint16 ;; FFI_TYPE_SMALL_STRUCT_2B dd offset cs_retint ;; FFI_TYPE_SMALL_STRUCT_4B + dd offset cs_retmsstruct ;; FFI_TYPE_MS_STRUCT + +cs_retuint8: + movzx eax, BYTE PTR [ecx] + jmp cs_epilogue + +cs_retsint8: + movsx eax, BYTE PTR [ecx] + jmp cs_epilogue -cs_retint8: - mov al, [ecx] +cs_retuint16: + movzx eax, WORD PTR [ecx] jmp cs_epilogue -cs_retint16: - mov ax, [ecx] +cs_retsint16: + movsx eax, WORD PTR [ecx] jmp cs_epilogue cs_retint: @@ -252,6 +277,12 @@ cs_retstruct: ;; Epilogue code is autogenerated. ret 4 +cs_retmsstruct: + ;; Caller expects us to return a pointer to the real return value. + mov eax, ecx + ;; Caller doesn't expects us to pop struct return value pointer hidden arg. + jmp cs_epilogue + cs_epilogue: ;; Epilogue code is autogenerated. ret @@ -264,19 +295,16 @@ ffi_closure_SYSV ENDP #define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4) #define CIF_FLAGS_OFFSET 20 -ffi_closure_raw_THISCALL PROC NEAR - push ebp - mov ebp, esp - push esi +ffi_closure_raw_THISCALL PROC NEAR USES esi FORCEFRAME sub esp, 36 mov esi, [eax + RAW_CLOSURE_CIF_OFFSET] ;; closure->cif mov edx, [eax + RAW_CLOSURE_USER_DATA_OFFSET] ;; closure->user_data mov [esp + 12], edx - lea edx, [ebp + 12], edx + lea edx, [ebp + 12] jmp stubraw -ffi_closure_raw_SYSV ENDP +ffi_closure_raw_THISCALL ENDP -ffi_closure_raw_SYSV PROC NEAR USES esi +ffi_closure_raw_SYSV PROC NEAR USES esi FORCEFRAME ;; the ffi_closure ctx is passed in eax by the trampoline. sub esp, 40 @@ -284,7 +312,7 @@ ffi_closure_raw_SYSV PROC NEAR USES esi mov edx, [eax + RAW_CLOSURE_USER_DATA_OFFSET] ;; closure->user_data mov [esp + 12], edx ;; user_data lea edx, [ebp + 8] -stubraw: +stubraw:: mov [esp + 8], edx ;; raw_args lea edx, [ebp - 24] mov [esp + 4], edx ;; &res @@ -302,26 +330,35 @@ cr_jumpdata: dd offset cr_retfloat ;; FFI_TYPE_FLOAT dd offset cr_retdouble ;; FFI_TYPE_DOUBLE dd offset cr_retlongdouble ;; FFI_TYPE_LONGDOUBLE - dd offset cr_retint8 ;; FFI_TYPE_UINT8 - dd offset cr_retint8 ;; FFI_TYPE_SINT8 - dd offset cr_retint16 ;; FFI_TYPE_UINT16 - dd offset cr_retint16 ;; FFI_TYPE_SINT16 + dd offset cr_retuint8 ;; FFI_TYPE_UINT8 + dd offset cr_retsint8 ;; FFI_TYPE_SINT8 + dd offset cr_retuint16 ;; FFI_TYPE_UINT16 + dd offset cr_retsint16 ;; FFI_TYPE_SINT16 dd offset cr_retint ;; FFI_TYPE_UINT32 dd offset cr_retint ;; FFI_TYPE_SINT32 dd offset cr_retint64 ;; FFI_TYPE_UINT64 dd offset cr_retint64 ;; FFI_TYPE_SINT64 dd offset cr_epilogue ;; FFI_TYPE_STRUCT dd offset cr_retint ;; FFI_TYPE_POINTER - dd offset cr_retint8 ;; FFI_TYPE_SMALL_STRUCT_1B - dd offset cr_retint16 ;; FFI_TYPE_SMALL_STRUCT_2B + dd offset cr_retsint8 ;; FFI_TYPE_SMALL_STRUCT_1B + dd offset cr_retsint16 ;; FFI_TYPE_SMALL_STRUCT_2B dd offset cr_retint ;; FFI_TYPE_SMALL_STRUCT_4B + dd offset cr_epilogue ;; FFI_TYPE_MS_STRUCT + +cr_retuint8: + movzx eax, BYTE PTR [ecx] + jmp cr_epilogue + +cr_retsint8: + movsx eax, BYTE PTR [ecx] + jmp cr_epilogue -cr_retint8: - mov al, [ecx] +cr_retuint16: + movzx eax, WORD PTR [ecx] jmp cr_epilogue -cr_retint16: - mov ax, [ecx] +cr_retsint16: + movsx eax, WORD PTR [ecx] jmp cr_epilogue cr_retint: @@ -375,26 +412,34 @@ cd_jumpdata: dd offset cd_retfloat ;; FFI_TYPE_FLOAT dd offset cd_retdouble ;; FFI_TYPE_DOUBLE dd offset cd_retlongdouble ;; FFI_TYPE_LONGDOUBLE - dd offset cd_retint8 ;; FFI_TYPE_UINT8 - dd offset cd_retint8 ;; FFI_TYPE_SINT8 - dd offset cd_retint16 ;; FFI_TYPE_UINT16 - dd offset cd_retint16 ;; FFI_TYPE_SINT16 + dd offset cd_retuint8 ;; FFI_TYPE_UINT8 + dd offset cd_retsint8 ;; FFI_TYPE_SINT8 + dd offset cd_retuint16 ;; FFI_TYPE_UINT16 + dd offset cd_retsint16 ;; FFI_TYPE_SINT16 dd offset cd_retint ;; FFI_TYPE_UINT32 dd offset cd_retint ;; FFI_TYPE_SINT32 dd offset cd_retint64 ;; FFI_TYPE_UINT64 dd offset cd_retint64 ;; FFI_TYPE_SINT64 dd offset cd_epilogue ;; FFI_TYPE_STRUCT dd offset cd_retint ;; FFI_TYPE_POINTER - dd offset cd_retint8 ;; FFI_TYPE_SMALL_STRUCT_1B - dd offset cd_retint16 ;; FFI_TYPE_SMALL_STRUCT_2B + dd offset cd_retsint8 ;; FFI_TYPE_SMALL_STRUCT_1B + dd offset cd_retsint16 ;; FFI_TYPE_SMALL_STRUCT_2B dd offset cd_retint ;; FFI_TYPE_SMALL_STRUCT_4B -cd_retint8: - mov al, [ecx] +cd_retuint8: + movzx eax, BYTE PTR [ecx] + jmp cd_epilogue + +cd_retsint8: + movsx eax, BYTE PTR [ecx] jmp cd_epilogue -cd_retint16: - mov ax, [ecx] +cd_retuint16: + movzx eax, WORD PTR [ecx] + jmp cd_epilogue + +cd_retsint16: + movsx eax, WORD PTR [ecx] jmp cd_epilogue cd_retint: @@ -515,6 +560,7 @@ _ffi_call_win32: .long .Lretstruct1b /* FFI_TYPE_SMALL_STRUCT_1B */ .long .Lretstruct2b /* FFI_TYPE_SMALL_STRUCT_2B */ .long .Lretstruct4b /* FFI_TYPE_SMALL_STRUCT_4B */ + .long .Lretstruct /* FFI_TYPE_MS_STRUCT */ 1: add %ecx, %ecx add %ecx, %ecx @@ -657,6 +703,7 @@ _ffi_closure_SYSV: .long .Lcls_retstruct1 /* FFI_TYPE_SMALL_STRUCT_1B */ .long .Lcls_retstruct2 /* FFI_TYPE_SMALL_STRUCT_2B */ .long .Lcls_retstruct4 /* FFI_TYPE_SMALL_STRUCT_4B */ + .long .Lcls_retmsstruct /* FFI_TYPE_MS_STRUCT */ 1: add %eax, %eax @@ -721,6 +768,12 @@ _ffi_closure_SYSV: popl %ebp ret $0x4 +.Lcls_retmsstruct: + # Caller expects us to return a pointer to the real return value. + mov %ecx, %eax + # Caller doesn't expects us to pop struct return value pointer hidden arg. + jmp .Lcls_epilogue + .Lcls_noretval: .Lcls_epilogue: movl %ebp, %esp @@ -798,6 +851,7 @@ _ffi_closure_raw_SYSV: .long .Lrcls_retstruct1 /* FFI_TYPE_SMALL_STRUCT_1B */ .long .Lrcls_retstruct2 /* FFI_TYPE_SMALL_STRUCT_2B */ .long .Lrcls_retstruct4 /* FFI_TYPE_SMALL_STRUCT_4B */ + .long .Lrcls_retstruct /* FFI_TYPE_MS_STRUCT */ 1: add %eax, %eax add %eax, %eax diff --git a/libffi/testsuite/Makefile.am b/libffi/testsuite/Makefile.am index f94ca00..146fdf9 100644 --- a/libffi/testsuite/Makefile.am +++ b/libffi/testsuite/Makefile.am @@ -14,3 +14,72 @@ RUNTEST = `if [ -f $(top_srcdir)/../dejagnu/runtest ] ; then \ AM_RUNTESTFLAGS = CLEANFILES = *.exe core* *.log *.sum + +EXTRA_DIST = config/default.exp libffi.call/cls_19byte.c \ +libffi.call/cls_align_longdouble_split.c libffi.call/closure_loc_fn0.c \ +libffi.call/cls_schar.c libffi.call/closure_fn1.c \ +libffi.call/many2_win32.c libffi.call/return_ul.c \ +libffi.call/cls_align_double.c libffi.call/return_fl2.c \ +libffi.call/cls_1_1byte.c libffi.call/cls_64byte.c \ +libffi.call/nested_struct7.c libffi.call/cls_align_sint32.c \ +libffi.call/nested_struct2.c libffi.call/ffitest.h \ +libffi.call/nested_struct4.c libffi.call/cls_multi_ushort.c \ +libffi.call/struct3.c libffi.call/cls_3byte1.c \ +libffi.call/cls_16byte.c libffi.call/struct8.c \ +libffi.call/nested_struct8.c libffi.call/cls_multi_sshort.c \ +libffi.call/cls_3byte2.c libffi.call/fastthis2_win32.c \ +libffi.call/cls_pointer.c libffi.call/err_bad_typedef.c \ +libffi.call/cls_4_1byte.c libffi.call/cls_9byte2.c \ +libffi.call/cls_multi_schar.c libffi.call/stret_medium2.c \ +libffi.call/cls_5_1_byte.c libffi.call/call.exp \ +libffi.call/cls_double.c libffi.call/cls_align_sint16.c \ +libffi.call/cls_uint.c libffi.call/return_ll1.c \ +libffi.call/nested_struct3.c libffi.call/cls_20byte1.c \ +libffi.call/closure_fn4.c libffi.call/cls_uchar.c \ +libffi.call/struct2.c libffi.call/cls_7byte.c libffi.call/strlen.c \ +libffi.call/many.c libffi.call/testclosure.c libffi.call/return_fl.c \ +libffi.call/struct5.c libffi.call/cls_12byte.c \ +libffi.call/cls_multi_sshortchar.c \ +libffi.call/cls_align_longdouble_split2.c libffi.call/return_dbl2.c \ +libffi.call/return_fl3.c libffi.call/stret_medium.c \ +libffi.call/nested_struct6.c libffi.call/a.out \ +libffi.call/closure_fn3.c libffi.call/float3.c libffi.call/many2.c \ +libffi.call/closure_stdcall.c libffi.call/cls_align_uint16.c \ +libffi.call/cls_9byte1.c libffi.call/closure_fn6.c \ +libffi.call/cls_double_va.c libffi.call/cls_align_pointer.c \ +libffi.call/cls_align_longdouble.c libffi.call/closure_fn2.c \ +libffi.call/cls_sshort.c libffi.call/many_win32.c \ +libffi.call/nested_struct.c libffi.call/cls_20byte.c \ +libffi.call/cls_longdouble.c libffi.call/cls_multi_uchar.c \ +libffi.call/return_uc.c libffi.call/closure_thiscall.c \ +libffi.call/cls_18byte.c libffi.call/cls_8byte.c \ +libffi.call/promotion.c libffi.call/struct1_win32.c \ +libffi.call/return_dbl.c libffi.call/cls_24byte.c \ +libffi.call/struct4.c libffi.call/cls_6byte.c \ +libffi.call/cls_align_uint32.c libffi.call/float.c \ +libffi.call/float1.c libffi.call/float_va.c libffi.call/negint.c \ +libffi.call/return_dbl1.c libffi.call/cls_3_1byte.c \ +libffi.call/cls_align_float.c libffi.call/return_fl1.c \ +libffi.call/nested_struct10.c libffi.call/nested_struct5.c \ +libffi.call/fastthis1_win32.c libffi.call/cls_align_sint64.c \ +libffi.call/stret_large2.c libffi.call/return_sl.c \ +libffi.call/closure_fn0.c libffi.call/cls_5byte.c \ +libffi.call/cls_2byte.c libffi.call/float2.c \ +libffi.call/cls_dbls_struct.c libffi.call/cls_sint.c \ +libffi.call/stret_large.c libffi.call/cls_ulonglong.c \ +libffi.call/cls_ushort.c libffi.call/nested_struct1.c \ +libffi.call/err_bad_abi.c libffi.call/cls_longdouble_va.c \ +libffi.call/cls_float.c libffi.call/cls_pointer_stack.c \ +libffi.call/pyobjc-tc.c libffi.call/cls_multi_ushortchar.c \ +libffi.call/struct1.c libffi.call/nested_struct9.c \ +libffi.call/huge_struct.c libffi.call/problem1.c libffi.call/float4.c \ +libffi.call/fastthis3_win32.c libffi.call/return_ldl.c \ +libffi.call/strlen2_win32.c libffi.call/closure_fn5.c \ +libffi.call/struct2_win32.c libffi.call/struct6.c \ +libffi.call/return_ll.c libffi.call/struct9.c libffi.call/return_sc.c \ +libffi.call/struct7.c libffi.call/cls_align_uint64.c \ +libffi.call/cls_4byte.c libffi.call/strlen_win32.c \ +libffi.call/cls_6_1_byte.c libffi.call/cls_7_1_byte.c \ +libffi.special/unwindtest.cc libffi.special/special.exp \ +libffi.special/unwindtest_ffi_call.cc libffi.special/ffitestcxx.h \ +lib/wrapper.exp lib/target-libpath.exp lib/libffi.exp diff --git a/libffi/testsuite/Makefile.in b/libffi/testsuite/Makefile.in index fae969b..44ca9c2 100644 --- a/libffi/testsuite/Makefile.in +++ b/libffi/testsuite/Makefile.in @@ -1,9 +1,9 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. +# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -15,6 +15,23 @@ @SET_MAKE@ VPATH = @srcdir@ +am__make_dryrun = \ + { \ + am__dry=no; \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ + | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ + *) \ + for am__flg in $$MAKEFLAGS; do \ + case $$am__flg in \ + *=*|--*) ;; \ + *n*) am__dry=yes; break;; \ + esac; \ + done;; \ + esac; \ + test $$am__dry = yes; \ + } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -37,22 +54,32 @@ target_triplet = @target@ subdir = testsuite DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/../config/depstand.m4 \ - $(top_srcdir)/../config/lead-dot.m4 \ - $(top_srcdir)/../config/multi.m4 \ - $(top_srcdir)/../config/override.m4 \ - $(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \ - $(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \ - $(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/acinclude.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/asmcfi.m4 \ + $(top_srcdir)/m4/ax_cc_maxopt.m4 \ + $(top_srcdir)/m4/ax_cflags_warn_all.m4 \ + $(top_srcdir)/m4/ax_check_compile_flag.m4 \ + $(top_srcdir)/m4/ax_compiler_vendor.m4 \ + $(top_srcdir)/m4/ax_configure_args.m4 \ + $(top_srcdir)/m4/ax_enable_builddir.m4 \ + $(top_srcdir)/m4/ax_gcc_archflag.m4 \ + $(top_srcdir)/m4/ax_gcc_x86_cpuid.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) -mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs +mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/fficonfig.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = SOURCES = DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac DEJATOOL = $(PACKAGE) RUNTESTDEFAULTFLAGS = --tool $$tool --srcdir $$srcdir DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) @@ -77,6 +104,7 @@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ @@ -84,6 +112,7 @@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ +FFI_EXEC_TRAMPOLINE_TABLE = @FFI_EXEC_TRAMPOLINE_TABLE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_LONG_DOUBLE = @HAVE_LONG_DOUBLE@ @@ -102,6 +131,7 @@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ @@ -117,6 +147,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PRTDIAG = @PRTDIAG@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ @@ -129,6 +160,7 @@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ @@ -136,6 +168,7 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +ax_enable_builddir_sed = @ax_enable_builddir_sed@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -163,7 +196,6 @@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ -multi_basedir = @multi_basedir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ @@ -172,6 +204,7 @@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ +sys_symbol_underscore = @sys_symbol_underscore@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ @@ -195,6 +228,75 @@ RUNTEST = `if [ -f $(top_srcdir)/../dejagnu/runtest ] ; then \ else echo runtest; fi` CLEANFILES = *.exe core* *.log *.sum +EXTRA_DIST = config/default.exp libffi.call/cls_19byte.c \ +libffi.call/cls_align_longdouble_split.c libffi.call/closure_loc_fn0.c \ +libffi.call/cls_schar.c libffi.call/closure_fn1.c \ +libffi.call/many2_win32.c libffi.call/return_ul.c \ +libffi.call/cls_align_double.c libffi.call/return_fl2.c \ +libffi.call/cls_1_1byte.c libffi.call/cls_64byte.c \ +libffi.call/nested_struct7.c libffi.call/cls_align_sint32.c \ +libffi.call/nested_struct2.c libffi.call/ffitest.h \ +libffi.call/nested_struct4.c libffi.call/cls_multi_ushort.c \ +libffi.call/struct3.c libffi.call/cls_3byte1.c \ +libffi.call/cls_16byte.c libffi.call/struct8.c \ +libffi.call/nested_struct8.c libffi.call/cls_multi_sshort.c \ +libffi.call/cls_3byte2.c libffi.call/fastthis2_win32.c \ +libffi.call/cls_pointer.c libffi.call/err_bad_typedef.c \ +libffi.call/cls_4_1byte.c libffi.call/cls_9byte2.c \ +libffi.call/cls_multi_schar.c libffi.call/stret_medium2.c \ +libffi.call/cls_5_1_byte.c libffi.call/call.exp \ +libffi.call/cls_double.c libffi.call/cls_align_sint16.c \ +libffi.call/cls_uint.c libffi.call/return_ll1.c \ +libffi.call/nested_struct3.c libffi.call/cls_20byte1.c \ +libffi.call/closure_fn4.c libffi.call/cls_uchar.c \ +libffi.call/struct2.c libffi.call/cls_7byte.c libffi.call/strlen.c \ +libffi.call/many.c libffi.call/testclosure.c libffi.call/return_fl.c \ +libffi.call/struct5.c libffi.call/cls_12byte.c \ +libffi.call/cls_multi_sshortchar.c \ +libffi.call/cls_align_longdouble_split2.c libffi.call/return_dbl2.c \ +libffi.call/return_fl3.c libffi.call/stret_medium.c \ +libffi.call/nested_struct6.c libffi.call/a.out \ +libffi.call/closure_fn3.c libffi.call/float3.c libffi.call/many2.c \ +libffi.call/closure_stdcall.c libffi.call/cls_align_uint16.c \ +libffi.call/cls_9byte1.c libffi.call/closure_fn6.c \ +libffi.call/cls_double_va.c libffi.call/cls_align_pointer.c \ +libffi.call/cls_align_longdouble.c libffi.call/closure_fn2.c \ +libffi.call/cls_sshort.c libffi.call/many_win32.c \ +libffi.call/nested_struct.c libffi.call/cls_20byte.c \ +libffi.call/cls_longdouble.c libffi.call/cls_multi_uchar.c \ +libffi.call/return_uc.c libffi.call/closure_thiscall.c \ +libffi.call/cls_18byte.c libffi.call/cls_8byte.c \ +libffi.call/promotion.c libffi.call/struct1_win32.c \ +libffi.call/return_dbl.c libffi.call/cls_24byte.c \ +libffi.call/struct4.c libffi.call/cls_6byte.c \ +libffi.call/cls_align_uint32.c libffi.call/float.c \ +libffi.call/float1.c libffi.call/float_va.c libffi.call/negint.c \ +libffi.call/return_dbl1.c libffi.call/cls_3_1byte.c \ +libffi.call/cls_align_float.c libffi.call/return_fl1.c \ +libffi.call/nested_struct10.c libffi.call/nested_struct5.c \ +libffi.call/fastthis1_win32.c libffi.call/cls_align_sint64.c \ +libffi.call/stret_large2.c libffi.call/return_sl.c \ +libffi.call/closure_fn0.c libffi.call/cls_5byte.c \ +libffi.call/cls_2byte.c libffi.call/float2.c \ +libffi.call/cls_dbls_struct.c libffi.call/cls_sint.c \ +libffi.call/stret_large.c libffi.call/cls_ulonglong.c \ +libffi.call/cls_ushort.c libffi.call/nested_struct1.c \ +libffi.call/err_bad_abi.c libffi.call/cls_longdouble_va.c \ +libffi.call/cls_float.c libffi.call/cls_pointer_stack.c \ +libffi.call/pyobjc-tc.c libffi.call/cls_multi_ushortchar.c \ +libffi.call/struct1.c libffi.call/nested_struct9.c \ +libffi.call/huge_struct.c libffi.call/problem1.c libffi.call/float4.c \ +libffi.call/fastthis3_win32.c libffi.call/return_ldl.c \ +libffi.call/strlen2_win32.c libffi.call/closure_fn5.c \ +libffi.call/struct2_win32.c libffi.call/struct6.c \ +libffi.call/return_ll.c libffi.call/struct9.c libffi.call/return_sc.c \ +libffi.call/struct7.c libffi.call/cls_align_uint64.c \ +libffi.call/cls_4byte.c libffi.call/strlen_win32.c \ +libffi.call/cls_6_1_byte.c libffi.call/cls_7_1_byte.c \ +libffi.special/unwindtest.cc libffi.special/special.exp \ +libffi.special/unwindtest_ffi_call.cc libffi.special/ffitestcxx.h \ +lib/wrapper.exp lib/target-libpath.exp lib/libffi.exp + all: all-am .SUFFIXES: @@ -242,7 +344,7 @@ CTAGS: check-DEJAGNU: site.exp - srcdir=`$(am__cd) $(srcdir) && pwd`; export srcdir; \ + srcdir='$(srcdir)'; export srcdir; \ EXPECT=$(EXPECT); export EXPECT; \ runtest=$(RUNTEST); \ if $(SHELL) -c "$$runtest --version" > /dev/null 2>&1; then \ @@ -253,12 +355,12 @@ check-DEJAGNU: site.exp else echo "WARNING: could not find \`runtest'" 1>&2; :;\ fi; \ exit $$exit_status -site.exp: Makefile +site.exp: Makefile $(EXTRA_DEJAGNU_SITE_CONFIG) @echo 'Making a new site.exp file...' @echo '## these variables are automatically generated by make ##' >site.tmp @echo '# Do not edit here. If you wish to override these values' >>site.tmp @echo '# edit the last section' >>site.tmp - @echo 'set srcdir $(srcdir)' >>site.tmp + @echo 'set srcdir "$(srcdir)"' >>site.tmp @echo "set objdir `pwd`" >>site.tmp @echo 'set build_alias "$(build_alias)"' >>site.tmp @echo 'set build_triplet $(build_triplet)' >>site.tmp @@ -266,9 +368,16 @@ site.exp: Makefile @echo 'set host_triplet $(host_triplet)' >>site.tmp @echo 'set target_alias "$(target_alias)"' >>site.tmp @echo 'set target_triplet $(target_triplet)' >>site.tmp - @echo '## All variables above are generated by configure. Do Not Edit ##' >>site.tmp - @test ! -f site.exp || \ - sed '1,/^## All variables above are.*##/ d' site.exp >> site.tmp + @list='$(EXTRA_DEJAGNU_SITE_CONFIG)'; for f in $$list; do \ + echo "## Begin content included from file $$f. Do not modify. ##" \ + && cat `test -f "$$f" || echo '$(srcdir)/'`$$f \ + && echo "## End content included from file $$f. ##" \ + || exit 1; \ + done >> site.tmp + @echo "## End of auto-generated content; you can edit from here. ##" >> site.tmp + @if test -f site.exp; then \ + sed -e '1,/^## End of auto-generated content.*##/d' site.exp >> site.tmp; \ + fi @-rm -f site.bak @test ! -f site.exp || mv site.exp site.bak @mv site.tmp site.exp @@ -324,10 +433,15 @@ install-am: all-am installcheck: installcheck-am install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi mostlyclean-generic: clean-generic: diff --git a/libffi/testsuite/lib/libffi.exp b/libffi/testsuite/lib/libffi.exp index 82d6652..8ee3f15 100644 --- a/libffi/testsuite/lib/libffi.exp +++ b/libffi/testsuite/lib/libffi.exp @@ -1,4 +1,4 @@ -# Copyright (C) 2003, 2005, 2008, 2009, 2010 Free Software Foundation, Inc. +# Copyright (C) 2003, 2005, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ proc load_gcc_lib { filename } { global srcdir - load_file $srcdir/../../gcc/testsuite/lib/$filename + load_file $srcdir/lib/$filename } load_lib dg.exp @@ -94,7 +94,6 @@ proc libffi-init { args } { global srcdir global blddirffi global objdir - global blddircxx global TOOL_OPTIONS global tool global libffi_include @@ -102,10 +101,8 @@ proc libffi-init { args } { global tool_root_dir global ld_library_path - set blddirffi [lookfor_file [get_multilibs] libffi] + set blddirffi [pwd]/.. verbose "libffi $blddirffi" - set blddircxx [lookfor_file [get_multilibs] libstdc++-v3] - verbose "libstdc++ $blddircxx" set gccdir [lookfor_file $tool_root_dir gcc/libgcc.a] if {$gccdir != ""} { @@ -132,8 +129,6 @@ proc libffi-init { args } { } # add the library path for libffi. append ld_library_path ":${blddirffi}/.libs" - # add the library path for libstdc++ as well. - append ld_library_path ":${blddircxx}/src/.libs" verbose "ld_library_path: $ld_library_path" @@ -146,7 +141,6 @@ proc libffi-init { args } { if { $libffi_dir != "" } { set libffi_dir [file dirname ${libffi_dir}] set libffi_link_flags "-L${libffi_dir}/.libs" - lappend libffi_link_flags "-L${blddircxx}/src/.libs" } set_ld_library_path_env_vars @@ -209,6 +203,10 @@ proc libffi_target_compile { source dest type options } { lappend options "libs= -lffi" + if { [string match "aarch64*-*-linux*" $target_triplet] } { + lappend options "libs= -lpthread" + } + verbose "options: $options" return [target_compile $source $dest $type $options] } diff --git a/libffi/testsuite/libffi.call/closure_stdcall.c b/libffi/testsuite/libffi.call/closure_stdcall.c index 6bfcc1f..1407f02 100644 --- a/libffi/testsuite/libffi.call/closure_stdcall.c +++ b/libffi/testsuite/libffi.call/closure_stdcall.c @@ -49,9 +49,17 @@ int main (void) CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_stdcall, (void *) 3 /* userdata */, code) == FFI_OK); +#ifdef _MSC_VER + __asm { mov sp_pre, esp } +#else asm volatile (" movl %%esp,%0" : "=g" (sp_pre)); +#endif res = (*(closure_test_type0)code)(0, 1, 2, 3); +#ifdef _MSC_VER + __asm { mov sp_post, esp } +#else asm volatile (" movl %%esp,%0" : "=g" (sp_post)); +#endif /* { dg-output "0 1 2 3: 9" } */ printf("res: %d\n",res); diff --git a/libffi/testsuite/libffi.call/closure_thiscall.c b/libffi/testsuite/libffi.call/closure_thiscall.c index 6c46f35..0f93649 100644 --- a/libffi/testsuite/libffi.call/closure_thiscall.c +++ b/libffi/testsuite/libffi.call/closure_thiscall.c @@ -49,9 +49,17 @@ int main (void) CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_thiscall, (void *) 3 /* userdata */, code) == FFI_OK); +#ifdef _MSC_VER + __asm { mov sp_pre, esp } +#else asm volatile (" movl %%esp,%0" : "=g" (sp_pre)); +#endif res = (*(closure_test_type0)code)(0, 1, 2, 3); +#ifdef _MSC_VER + __asm { mov sp_post, esp } +#else asm volatile (" movl %%esp,%0" : "=g" (sp_post)); +#endif /* { dg-output "0 1 2 3: 9" } */ printf("res: %d\n",res); diff --git a/libffi/testsuite/libffi.call/cls_12byte.c b/libffi/testsuite/libffi.call/cls_12byte.c index f0a334f..ea0825d 100644 --- a/libffi/testsuite/libffi.call/cls_12byte.c +++ b/libffi/testsuite/libffi.call/cls_12byte.c @@ -49,15 +49,15 @@ int main (void) ffi_type cls_struct_type; ffi_type* dbl_arg_types[5]; + struct cls_struct_12byte h_dbl = { 7, 4, 9 }; + struct cls_struct_12byte j_dbl = { 1, 5, 3 }; + struct cls_struct_12byte res_dbl; + cls_struct_type.size = 0; cls_struct_type.alignment = 0; cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.elements = cls_struct_fields; - struct cls_struct_12byte h_dbl = { 7, 4, 9 }; - struct cls_struct_12byte j_dbl = { 1, 5, 3 }; - struct cls_struct_12byte res_dbl; - cls_struct_fields[0] = &ffi_type_sint; cls_struct_fields[1] = &ffi_type_sint; cls_struct_fields[2] = &ffi_type_sint; diff --git a/libffi/testsuite/libffi.call/cls_16byte.c b/libffi/testsuite/libffi.call/cls_16byte.c index 9b9292a..89a08a2 100644 --- a/libffi/testsuite/libffi.call/cls_16byte.c +++ b/libffi/testsuite/libffi.call/cls_16byte.c @@ -50,15 +50,15 @@ int main (void) ffi_type cls_struct_type; ffi_type* dbl_arg_types[5]; + struct cls_struct_16byte h_dbl = { 7, 8.0, 9 }; + struct cls_struct_16byte j_dbl = { 1, 9.0, 3 }; + struct cls_struct_16byte res_dbl; + cls_struct_type.size = 0; cls_struct_type.alignment = 0; cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.elements = cls_struct_fields; - struct cls_struct_16byte h_dbl = { 7, 8.0, 9 }; - struct cls_struct_16byte j_dbl = { 1, 9.0, 3 }; - struct cls_struct_16byte res_dbl; - cls_struct_fields[0] = &ffi_type_sint; cls_struct_fields[1] = &ffi_type_double; cls_struct_fields[2] = &ffi_type_sint; diff --git a/libffi/testsuite/libffi.call/cls_18byte.c b/libffi/testsuite/libffi.call/cls_18byte.c index 40c8c6d..9f75da8 100644 --- a/libffi/testsuite/libffi.call/cls_18byte.c +++ b/libffi/testsuite/libffi.call/cls_18byte.c @@ -54,15 +54,15 @@ int main (void) ffi_type cls_struct_type; ffi_type* dbl_arg_types[3]; + struct cls_struct_18byte g_dbl = { 1.0, 127, 126, 3.0 }; + struct cls_struct_18byte f_dbl = { 4.0, 125, 124, 5.0 }; + struct cls_struct_18byte res_dbl; + cls_struct_type.size = 0; cls_struct_type.alignment = 0; cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.elements = cls_struct_fields; - struct cls_struct_18byte g_dbl = { 1.0, 127, 126, 3.0 }; - struct cls_struct_18byte f_dbl = { 4.0, 125, 124, 5.0 }; - struct cls_struct_18byte res_dbl; - cls_struct_fields[0] = &ffi_type_double; cls_struct_fields[1] = &ffi_type_uchar; cls_struct_fields[2] = &ffi_type_uchar; diff --git a/libffi/testsuite/libffi.call/cls_19byte.c b/libffi/testsuite/libffi.call/cls_19byte.c index aa64248..278794b 100644 --- a/libffi/testsuite/libffi.call/cls_19byte.c +++ b/libffi/testsuite/libffi.call/cls_19byte.c @@ -57,15 +57,15 @@ int main (void) ffi_type cls_struct_type; ffi_type* dbl_arg_types[3]; + struct cls_struct_19byte g_dbl = { 1.0, 127, 126, 3.0, 120 }; + struct cls_struct_19byte f_dbl = { 4.0, 125, 124, 5.0, 119 }; + struct cls_struct_19byte res_dbl; + cls_struct_type.size = 0; cls_struct_type.alignment = 0; cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.elements = cls_struct_fields; - struct cls_struct_19byte g_dbl = { 1.0, 127, 126, 3.0, 120 }; - struct cls_struct_19byte f_dbl = { 4.0, 125, 124, 5.0, 119 }; - struct cls_struct_19byte res_dbl; - cls_struct_fields[0] = &ffi_type_double; cls_struct_fields[1] = &ffi_type_uchar; cls_struct_fields[2] = &ffi_type_uchar; diff --git a/libffi/testsuite/libffi.call/cls_1_1byte.c b/libffi/testsuite/libffi.call/cls_1_1byte.c index b9402d6..82492c0 100644 --- a/libffi/testsuite/libffi.call/cls_1_1byte.c +++ b/libffi/testsuite/libffi.call/cls_1_1byte.c @@ -50,15 +50,15 @@ int main (void) ffi_type cls_struct_type; ffi_type* dbl_arg_types[5]; + struct cls_struct_1_1byte g_dbl = { 12 }; + struct cls_struct_1_1byte f_dbl = { 178 }; + struct cls_struct_1_1byte res_dbl; + cls_struct_type.size = 0; cls_struct_type.alignment = 0; cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.elements = cls_struct_fields; - struct cls_struct_1_1byte g_dbl = { 12 }; - struct cls_struct_1_1byte f_dbl = { 178 }; - struct cls_struct_1_1byte res_dbl; - cls_struct_fields[0] = &ffi_type_uchar; cls_struct_fields[1] = NULL; diff --git a/libffi/testsuite/libffi.call/cls_20byte.c b/libffi/testsuite/libffi.call/cls_20byte.c index 80dd7ac..3f8bb28 100644 --- a/libffi/testsuite/libffi.call/cls_20byte.c +++ b/libffi/testsuite/libffi.call/cls_20byte.c @@ -50,15 +50,15 @@ int main (void) ffi_type cls_struct_type; ffi_type* dbl_arg_types[5]; + struct cls_struct_20byte g_dbl = { 1.0, 2.0, 3 }; + struct cls_struct_20byte f_dbl = { 4.0, 5.0, 7 }; + struct cls_struct_20byte res_dbl; + cls_struct_type.size = 0; cls_struct_type.alignment = 0; cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.elements = cls_struct_fields; - struct cls_struct_20byte g_dbl = { 1.0, 2.0, 3 }; - struct cls_struct_20byte f_dbl = { 4.0, 5.0, 7 }; - struct cls_struct_20byte res_dbl; - cls_struct_fields[0] = &ffi_type_double; cls_struct_fields[1] = &ffi_type_double; cls_struct_fields[2] = &ffi_type_sint; diff --git a/libffi/testsuite/libffi.call/cls_20byte1.c b/libffi/testsuite/libffi.call/cls_20byte1.c index 50bcbbf..6562727 100644 --- a/libffi/testsuite/libffi.call/cls_20byte1.c +++ b/libffi/testsuite/libffi.call/cls_20byte1.c @@ -52,15 +52,15 @@ int main (void) ffi_type cls_struct_type; ffi_type* dbl_arg_types[3]; + struct cls_struct_20byte g_dbl = { 1, 2.0, 3.0 }; + struct cls_struct_20byte f_dbl = { 4, 5.0, 7.0 }; + struct cls_struct_20byte res_dbl; + cls_struct_type.size = 0; cls_struct_type.alignment = 0; cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.elements = cls_struct_fields; - struct cls_struct_20byte g_dbl = { 1, 2.0, 3.0 }; - struct cls_struct_20byte f_dbl = { 4, 5.0, 7.0 }; - struct cls_struct_20byte res_dbl; - cls_struct_fields[0] = &ffi_type_sint; cls_struct_fields[1] = &ffi_type_double; cls_struct_fields[2] = &ffi_type_double; diff --git a/libffi/testsuite/libffi.call/cls_24byte.c b/libffi/testsuite/libffi.call/cls_24byte.c index 46a6eb4..1d82f6e 100644 --- a/libffi/testsuite/libffi.call/cls_24byte.c +++ b/libffi/testsuite/libffi.call/cls_24byte.c @@ -61,17 +61,17 @@ int main (void) ffi_type cls_struct_type; ffi_type* dbl_arg_types[5]; - cls_struct_type.size = 0; - cls_struct_type.alignment = 0; - cls_struct_type.type = FFI_TYPE_STRUCT; - cls_struct_type.elements = cls_struct_fields; - struct cls_struct_24byte e_dbl = { 9.0, 2.0, 6, 5.0 }; struct cls_struct_24byte f_dbl = { 1.0, 2.0, 3, 7.0 }; struct cls_struct_24byte g_dbl = { 4.0, 5.0, 7, 9.0 }; struct cls_struct_24byte h_dbl = { 8.0, 6.0, 1, 4.0 }; struct cls_struct_24byte res_dbl; + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + cls_struct_fields[0] = &ffi_type_double; cls_struct_fields[1] = &ffi_type_double; cls_struct_fields[2] = &ffi_type_sint; diff --git a/libffi/testsuite/libffi.call/cls_2byte.c b/libffi/testsuite/libffi.call/cls_2byte.c index 101e130..81bb0a6 100644 --- a/libffi/testsuite/libffi.call/cls_2byte.c +++ b/libffi/testsuite/libffi.call/cls_2byte.c @@ -50,15 +50,15 @@ int main (void) ffi_type cls_struct_type; ffi_type* dbl_arg_types[5]; + struct cls_struct_2byte g_dbl = { 12, 127 }; + struct cls_struct_2byte f_dbl = { 1, 13 }; + struct cls_struct_2byte res_dbl; + cls_struct_type.size = 0; cls_struct_type.alignment = 0; cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.elements = cls_struct_fields; - struct cls_struct_2byte g_dbl = { 12, 127 }; - struct cls_struct_2byte f_dbl = { 1, 13 }; - struct cls_struct_2byte res_dbl; - cls_struct_fields[0] = &ffi_type_uchar; cls_struct_fields[1] = &ffi_type_uchar; cls_struct_fields[2] = NULL; diff --git a/libffi/testsuite/libffi.call/cls_3_1byte.c b/libffi/testsuite/libffi.call/cls_3_1byte.c index fc780c3..b782746 100644 --- a/libffi/testsuite/libffi.call/cls_3_1byte.c +++ b/libffi/testsuite/libffi.call/cls_3_1byte.c @@ -54,15 +54,15 @@ int main (void) ffi_type cls_struct_type; ffi_type* dbl_arg_types[5]; + struct cls_struct_3_1byte g_dbl = { 12, 13, 14 }; + struct cls_struct_3_1byte f_dbl = { 178, 179, 180 }; + struct cls_struct_3_1byte res_dbl; + cls_struct_type.size = 0; cls_struct_type.alignment = 0; cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.elements = cls_struct_fields; - struct cls_struct_3_1byte g_dbl = { 12, 13, 14 }; - struct cls_struct_3_1byte f_dbl = { 178, 179, 180 }; - struct cls_struct_3_1byte res_dbl; - cls_struct_fields[0] = &ffi_type_uchar; cls_struct_fields[1] = &ffi_type_uchar; cls_struct_fields[2] = &ffi_type_uchar; diff --git a/libffi/testsuite/libffi.call/cls_3byte1.c b/libffi/testsuite/libffi.call/cls_3byte1.c index 5705ce3..a02c463 100644 --- a/libffi/testsuite/libffi.call/cls_3byte1.c +++ b/libffi/testsuite/libffi.call/cls_3byte1.c @@ -50,15 +50,15 @@ int main (void) ffi_type cls_struct_type; ffi_type* dbl_arg_types[5]; + struct cls_struct_3byte g_dbl = { 12, 119 }; + struct cls_struct_3byte f_dbl = { 1, 15 }; + struct cls_struct_3byte res_dbl; + cls_struct_type.size = 0; cls_struct_type.alignment = 0; cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.elements = cls_struct_fields; - struct cls_struct_3byte g_dbl = { 12, 119 }; - struct cls_struct_3byte f_dbl = { 1, 15 }; - struct cls_struct_3byte res_dbl; - cls_struct_fields[0] = &ffi_type_ushort; cls_struct_fields[1] = &ffi_type_uchar; cls_struct_fields[2] = NULL; diff --git a/libffi/testsuite/libffi.call/cls_3byte2.c b/libffi/testsuite/libffi.call/cls_3byte2.c index 01770a0..c7251ce 100644 --- a/libffi/testsuite/libffi.call/cls_3byte2.c +++ b/libffi/testsuite/libffi.call/cls_3byte2.c @@ -50,15 +50,15 @@ int main (void) ffi_type cls_struct_type; ffi_type* dbl_arg_types[5]; + struct cls_struct_3byte_1 g_dbl = { 15, 125 }; + struct cls_struct_3byte_1 f_dbl = { 9, 19 }; + struct cls_struct_3byte_1 res_dbl; + cls_struct_type.size = 0; cls_struct_type.alignment = 0; cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.elements = cls_struct_fields; - struct cls_struct_3byte_1 g_dbl = { 15, 125 }; - struct cls_struct_3byte_1 f_dbl = { 9, 19 }; - struct cls_struct_3byte_1 res_dbl; - cls_struct_fields[0] = &ffi_type_uchar; cls_struct_fields[1] = &ffi_type_ushort; cls_struct_fields[2] = NULL; diff --git a/libffi/testsuite/libffi.call/cls_4_1byte.c b/libffi/testsuite/libffi.call/cls_4_1byte.c index f3806d7..2d6d8b6 100644 --- a/libffi/testsuite/libffi.call/cls_4_1byte.c +++ b/libffi/testsuite/libffi.call/cls_4_1byte.c @@ -56,15 +56,15 @@ int main (void) ffi_type cls_struct_type; ffi_type* dbl_arg_types[5]; + struct cls_struct_4_1byte g_dbl = { 12, 13, 14, 15 }; + struct cls_struct_4_1byte f_dbl = { 178, 179, 180, 181 }; + struct cls_struct_4_1byte res_dbl; + cls_struct_type.size = 0; cls_struct_type.alignment = 0; cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.elements = cls_struct_fields; - struct cls_struct_4_1byte g_dbl = { 12, 13, 14, 15 }; - struct cls_struct_4_1byte f_dbl = { 178, 179, 180, 181 }; - struct cls_struct_4_1byte res_dbl; - cls_struct_fields[0] = &ffi_type_uchar; cls_struct_fields[1] = &ffi_type_uchar; cls_struct_fields[2] = &ffi_type_uchar; diff --git a/libffi/testsuite/libffi.call/cls_4byte.c b/libffi/testsuite/libffi.call/cls_4byte.c index a1aba3c..4ac3787 100644 --- a/libffi/testsuite/libffi.call/cls_4byte.c +++ b/libffi/testsuite/libffi.call/cls_4byte.c @@ -50,15 +50,15 @@ int main (void) ffi_type cls_struct_type; ffi_type* dbl_arg_types[5]; + struct cls_struct_4byte g_dbl = { 127, 120 }; + struct cls_struct_4byte f_dbl = { 12, 128 }; + struct cls_struct_4byte res_dbl; + cls_struct_type.size = 0; cls_struct_type.alignment = 0; cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.elements = cls_struct_fields; - struct cls_struct_4byte g_dbl = { 127, 120 }; - struct cls_struct_4byte f_dbl = { 12, 128 }; - struct cls_struct_4byte res_dbl; - cls_struct_fields[0] = &ffi_type_ushort; cls_struct_fields[1] = &ffi_type_ushort; cls_struct_fields[2] = NULL; diff --git a/libffi/testsuite/libffi.call/cls_5_1_byte.c b/libffi/testsuite/libffi.call/cls_5_1_byte.c index 2ceba3d..ad9d51c 100644 --- a/libffi/testsuite/libffi.call/cls_5_1_byte.c +++ b/libffi/testsuite/libffi.call/cls_5_1_byte.c @@ -58,15 +58,15 @@ int main (void) ffi_type cls_struct_type; ffi_type* dbl_arg_types[5]; + struct cls_struct_5byte g_dbl = { 127, 120, 1, 3, 4 }; + struct cls_struct_5byte f_dbl = { 12, 128, 9, 3, 4 }; + struct cls_struct_5byte res_dbl = { 0, 0, 0, 0, 0 }; + cls_struct_type.size = 0; cls_struct_type.alignment = 0; cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.elements = cls_struct_fields; - struct cls_struct_5byte g_dbl = { 127, 120, 1, 3, 4 }; - struct cls_struct_5byte f_dbl = { 12, 128, 9, 3, 4 }; - struct cls_struct_5byte res_dbl = { 0, 0, 0, 0, 0 }; - cls_struct_fields[0] = &ffi_type_uchar; cls_struct_fields[1] = &ffi_type_uchar; cls_struct_fields[2] = &ffi_type_uchar; diff --git a/libffi/testsuite/libffi.call/cls_5byte.c b/libffi/testsuite/libffi.call/cls_5byte.c index 61d595c..4e0c000 100644 --- a/libffi/testsuite/libffi.call/cls_5byte.c +++ b/libffi/testsuite/libffi.call/cls_5byte.c @@ -53,15 +53,15 @@ int main (void) ffi_type cls_struct_type; ffi_type* dbl_arg_types[5]; + struct cls_struct_5byte g_dbl = { 127, 120, 1 }; + struct cls_struct_5byte f_dbl = { 12, 128, 9 }; + struct cls_struct_5byte res_dbl = { 0, 0, 0 }; + cls_struct_type.size = 0; cls_struct_type.alignment = 0; cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.elements = cls_struct_fields; - struct cls_struct_5byte g_dbl = { 127, 120, 1 }; - struct cls_struct_5byte f_dbl = { 12, 128, 9 }; - struct cls_struct_5byte res_dbl = { 0, 0, 0 }; - cls_struct_fields[0] = &ffi_type_ushort; cls_struct_fields[1] = &ffi_type_ushort; cls_struct_fields[2] = &ffi_type_uchar; diff --git a/libffi/testsuite/libffi.call/cls_64byte.c b/libffi/testsuite/libffi.call/cls_64byte.c index 576ebe0..a55edc2 100644 --- a/libffi/testsuite/libffi.call/cls_64byte.c +++ b/libffi/testsuite/libffi.call/cls_64byte.c @@ -66,17 +66,17 @@ int main (void) ffi_type cls_struct_type; ffi_type* dbl_arg_types[5]; - cls_struct_type.size = 0; - cls_struct_type.alignment = 0; - cls_struct_type.type = FFI_TYPE_STRUCT; - cls_struct_type.elements = cls_struct_fields; - struct cls_struct_64byte e_dbl = { 9.0, 2.0, 6.0, 5.0, 3.0, 4.0, 8.0, 1.0 }; struct cls_struct_64byte f_dbl = { 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 6.0, 7.0 }; struct cls_struct_64byte g_dbl = { 4.0, 5.0, 7.0, 9.0, 1.0, 1.0, 2.0, 9.0 }; struct cls_struct_64byte h_dbl = { 8.0, 6.0, 1.0, 4.0, 0.0, 3.0, 3.0, 1.0 }; struct cls_struct_64byte res_dbl; + cls_struct_type.size = 0; + cls_struct_type.alignment = 0; + cls_struct_type.type = FFI_TYPE_STRUCT; + cls_struct_type.elements = cls_struct_fields; + cls_struct_fields[0] = &ffi_type_double; cls_struct_fields[1] = &ffi_type_double; cls_struct_fields[2] = &ffi_type_double; diff --git a/libffi/testsuite/libffi.call/cls_6_1_byte.c b/libffi/testsuite/libffi.call/cls_6_1_byte.c index 9f2eff6..b4dcdba 100644 --- a/libffi/testsuite/libffi.call/cls_6_1_byte.c +++ b/libffi/testsuite/libffi.call/cls_6_1_byte.c @@ -60,15 +60,15 @@ int main (void) ffi_type cls_struct_type; ffi_type* dbl_arg_types[5]; + struct cls_struct_6byte g_dbl = { 127, 120, 1, 3, 4, 5 }; + struct cls_struct_6byte f_dbl = { 12, 128, 9, 3, 4, 5 }; + struct cls_struct_6byte res_dbl = { 0, 0, 0, 0, 0, 0 }; + cls_struct_type.size = 0; cls_struct_type.alignment = 0; cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.elements = cls_struct_fields; - struct cls_struct_6byte g_dbl = { 127, 120, 1, 3, 4, 5 }; - struct cls_struct_6byte f_dbl = { 12, 128, 9, 3, 4, 5 }; - struct cls_struct_6byte res_dbl = { 0, 0, 0, 0, 0, 0 }; - cls_struct_fields[0] = &ffi_type_uchar; cls_struct_fields[1] = &ffi_type_uchar; cls_struct_fields[2] = &ffi_type_uchar; diff --git a/libffi/testsuite/libffi.call/cls_6byte.c b/libffi/testsuite/libffi.call/cls_6byte.c index 73257b0..7406780 100644 --- a/libffi/testsuite/libffi.call/cls_6byte.c +++ b/libffi/testsuite/libffi.call/cls_6byte.c @@ -56,15 +56,15 @@ int main (void) ffi_type cls_struct_type; ffi_type* dbl_arg_types[5]; + struct cls_struct_6byte g_dbl = { 127, 120, 1, 128 }; + struct cls_struct_6byte f_dbl = { 12, 128, 9, 127 }; + struct cls_struct_6byte res_dbl; + cls_struct_type.size = 0; cls_struct_type.alignment = 0; cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.elements = cls_struct_fields; - struct cls_struct_6byte g_dbl = { 127, 120, 1, 128 }; - struct cls_struct_6byte f_dbl = { 12, 128, 9, 127 }; - struct cls_struct_6byte res_dbl; - cls_struct_fields[0] = &ffi_type_ushort; cls_struct_fields[1] = &ffi_type_ushort; cls_struct_fields[2] = &ffi_type_uchar; diff --git a/libffi/testsuite/libffi.call/cls_7_1_byte.c b/libffi/testsuite/libffi.call/cls_7_1_byte.c index 50d09c9..14a7e96 100644 --- a/libffi/testsuite/libffi.call/cls_7_1_byte.c +++ b/libffi/testsuite/libffi.call/cls_7_1_byte.c @@ -62,15 +62,15 @@ int main (void) ffi_type cls_struct_type; ffi_type* dbl_arg_types[5]; + struct cls_struct_7byte g_dbl = { 127, 120, 1, 3, 4, 5, 6 }; + struct cls_struct_7byte f_dbl = { 12, 128, 9, 3, 4, 5, 6 }; + struct cls_struct_7byte res_dbl = { 0, 0, 0, 0, 0, 0, 0 }; + cls_struct_type.size = 0; cls_struct_type.alignment = 0; cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.elements = cls_struct_fields; - struct cls_struct_7byte g_dbl = { 127, 120, 1, 3, 4, 5, 6 }; - struct cls_struct_7byte f_dbl = { 12, 128, 9, 3, 4, 5, 6 }; - struct cls_struct_7byte res_dbl = { 0, 0, 0, 0, 0, 0, 0 }; - cls_struct_fields[0] = &ffi_type_uchar; cls_struct_fields[1] = &ffi_type_uchar; cls_struct_fields[2] = &ffi_type_uchar; diff --git a/libffi/testsuite/libffi.call/cls_7byte.c b/libffi/testsuite/libffi.call/cls_7byte.c index f5c0000..1645cc6 100644 --- a/libffi/testsuite/libffi.call/cls_7byte.c +++ b/libffi/testsuite/libffi.call/cls_7byte.c @@ -55,15 +55,15 @@ int main (void) ffi_type cls_struct_type; ffi_type* dbl_arg_types[5]; + struct cls_struct_7byte g_dbl = { 127, 120, 1, 254 }; + struct cls_struct_7byte f_dbl = { 12, 128, 9, 255 }; + struct cls_struct_7byte res_dbl; + cls_struct_type.size = 0; cls_struct_type.alignment = 0; cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.elements = cls_struct_fields; - struct cls_struct_7byte g_dbl = { 127, 120, 1, 254 }; - struct cls_struct_7byte f_dbl = { 12, 128, 9, 255 }; - struct cls_struct_7byte res_dbl; - cls_struct_fields[0] = &ffi_type_ushort; cls_struct_fields[1] = &ffi_type_ushort; cls_struct_fields[2] = &ffi_type_uchar; diff --git a/libffi/testsuite/libffi.call/cls_8byte.c b/libffi/testsuite/libffi.call/cls_8byte.c index 4aa99d1..f6c1ea5 100644 --- a/libffi/testsuite/libffi.call/cls_8byte.c +++ b/libffi/testsuite/libffi.call/cls_8byte.c @@ -49,15 +49,15 @@ int main (void) ffi_type cls_struct_type; ffi_type* dbl_arg_types[5]; + struct cls_struct_8byte g_dbl = { 1, 2.0 }; + struct cls_struct_8byte f_dbl = { 4, 5.0 }; + struct cls_struct_8byte res_dbl; + cls_struct_type.size = 0; cls_struct_type.alignment = 0; cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.elements = cls_struct_fields; - struct cls_struct_8byte g_dbl = { 1, 2.0 }; - struct cls_struct_8byte f_dbl = { 4, 5.0 }; - struct cls_struct_8byte res_dbl; - cls_struct_fields[0] = &ffi_type_sint; cls_struct_fields[1] = &ffi_type_float; cls_struct_fields[2] = NULL; diff --git a/libffi/testsuite/libffi.call/cls_9byte1.c b/libffi/testsuite/libffi.call/cls_9byte1.c index cc5e9d6..0b85722 100644 --- a/libffi/testsuite/libffi.call/cls_9byte1.c +++ b/libffi/testsuite/libffi.call/cls_9byte1.c @@ -50,15 +50,15 @@ int main (void) ffi_type cls_struct_type; ffi_type* dbl_arg_types[3]; + struct cls_struct_9byte h_dbl = { 7, 8.0}; + struct cls_struct_9byte j_dbl = { 1, 9.0}; + struct cls_struct_9byte res_dbl; + cls_struct_type.size = 0; cls_struct_type.alignment = 0; cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.elements = cls_struct_fields; - struct cls_struct_9byte h_dbl = { 7, 8.0}; - struct cls_struct_9byte j_dbl = { 1, 9.0}; - struct cls_struct_9byte res_dbl; - cls_struct_fields[0] = &ffi_type_sint; cls_struct_fields[1] = &ffi_type_double; cls_struct_fields[2] = NULL; diff --git a/libffi/testsuite/libffi.call/cls_9byte2.c b/libffi/testsuite/libffi.call/cls_9byte2.c index 5c0ba0d..edf991d 100644 --- a/libffi/testsuite/libffi.call/cls_9byte2.c +++ b/libffi/testsuite/libffi.call/cls_9byte2.c @@ -50,15 +50,15 @@ int main (void) ffi_type cls_struct_type; ffi_type* dbl_arg_types[3]; + struct cls_struct_9byte h_dbl = { 7.0, 8}; + struct cls_struct_9byte j_dbl = { 1.0, 9}; + struct cls_struct_9byte res_dbl; + cls_struct_type.size = 0; cls_struct_type.alignment = 0; cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.elements = cls_struct_fields; - struct cls_struct_9byte h_dbl = { 7.0, 8}; - struct cls_struct_9byte j_dbl = { 1.0, 9}; - struct cls_struct_9byte res_dbl; - cls_struct_fields[0] = &ffi_type_double; cls_struct_fields[1] = &ffi_type_sint; cls_struct_fields[2] = NULL; diff --git a/libffi/testsuite/libffi.call/cls_align_double.c b/libffi/testsuite/libffi.call/cls_align_double.c index 22b94d5..aad5f3c 100644 --- a/libffi/testsuite/libffi.call/cls_align_double.c +++ b/libffi/testsuite/libffi.call/cls_align_double.c @@ -52,15 +52,15 @@ int main (void) ffi_type cls_struct_type; ffi_type* dbl_arg_types[5]; + struct cls_struct_align g_dbl = { 12, 4951, 127 }; + struct cls_struct_align f_dbl = { 1, 9320, 13 }; + struct cls_struct_align res_dbl; + cls_struct_type.size = 0; cls_struct_type.alignment = 0; cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.elements = cls_struct_fields; - struct cls_struct_align g_dbl = { 12, 4951, 127 }; - struct cls_struct_align f_dbl = { 1, 9320, 13 }; - struct cls_struct_align res_dbl; - cls_struct_fields[0] = &ffi_type_uchar; cls_struct_fields[1] = &ffi_type_double; cls_struct_fields[2] = &ffi_type_uchar; diff --git a/libffi/testsuite/libffi.call/cls_align_float.c b/libffi/testsuite/libffi.call/cls_align_float.c index 62637f2..37e0855 100644 --- a/libffi/testsuite/libffi.call/cls_align_float.c +++ b/libffi/testsuite/libffi.call/cls_align_float.c @@ -50,15 +50,15 @@ int main (void) ffi_type cls_struct_type; ffi_type* dbl_arg_types[5]; + struct cls_struct_align g_dbl = { 12, 4951, 127 }; + struct cls_struct_align f_dbl = { 1, 9320, 13 }; + struct cls_struct_align res_dbl; + cls_struct_type.size = 0; cls_struct_type.alignment = 0; cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.elements = cls_struct_fields; - struct cls_struct_align g_dbl = { 12, 4951, 127 }; - struct cls_struct_align f_dbl = { 1, 9320, 13 }; - struct cls_struct_align res_dbl; - cls_struct_fields[0] = &ffi_type_uchar; cls_struct_fields[1] = &ffi_type_float; cls_struct_fields[2] = &ffi_type_uchar; diff --git a/libffi/testsuite/libffi.call/cls_align_longdouble.c b/libffi/testsuite/libffi.call/cls_align_longdouble.c index af38060..b3322d8 100644 --- a/libffi/testsuite/libffi.call/cls_align_longdouble.c +++ b/libffi/testsuite/libffi.call/cls_align_longdouble.c @@ -51,15 +51,15 @@ int main (void) ffi_type cls_struct_type; ffi_type* dbl_arg_types[5]; + struct cls_struct_align g_dbl = { 12, 4951, 127 }; + struct cls_struct_align f_dbl = { 1, 9320, 13 }; + struct cls_struct_align res_dbl; + cls_struct_type.size = 0; cls_struct_type.alignment = 0; cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.elements = cls_struct_fields; - struct cls_struct_align g_dbl = { 12, 4951, 127 }; - struct cls_struct_align f_dbl = { 1, 9320, 13 }; - struct cls_struct_align res_dbl; - cls_struct_fields[0] = &ffi_type_uchar; cls_struct_fields[1] = &ffi_type_longdouble; cls_struct_fields[2] = &ffi_type_uchar; diff --git a/libffi/testsuite/libffi.call/cls_align_longdouble_split.c b/libffi/testsuite/libffi.call/cls_align_longdouble_split.c index a3732bd..15f9365 100644 --- a/libffi/testsuite/libffi.call/cls_align_longdouble_split.c +++ b/libffi/testsuite/libffi.call/cls_align_longdouble_split.c @@ -87,15 +87,15 @@ int main (void) ffi_type cls_struct_type; ffi_type* dbl_arg_types[3]; + struct cls_struct_align g_dbl = { 1, 2, 3, 4, 5, 6, 7 }; + struct cls_struct_align f_dbl = { 8, 9, 10, 11, 12, 13, 14 }; + struct cls_struct_align res_dbl; + cls_struct_type.size = 0; cls_struct_type.alignment = 0; cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.elements = cls_struct_fields; - struct cls_struct_align g_dbl = { 1, 2, 3, 4, 5, 6, 7 }; - struct cls_struct_align f_dbl = { 8, 9, 10, 11, 12, 13, 14 }; - struct cls_struct_align res_dbl; - cls_struct_fields[0] = &ffi_type_longdouble; cls_struct_fields[1] = &ffi_type_longdouble; cls_struct_fields[2] = &ffi_type_longdouble; diff --git a/libffi/testsuite/libffi.call/cls_align_longdouble_split2.c b/libffi/testsuite/libffi.call/cls_align_longdouble_split2.c index 63a0f76..ca1c356 100644 --- a/libffi/testsuite/libffi.call/cls_align_longdouble_split2.c +++ b/libffi/testsuite/libffi.call/cls_align_longdouble_split2.c @@ -67,15 +67,15 @@ int main (void) ffi_type cls_struct_type; ffi_type* dbl_arg_types[3]; + struct cls_struct_align g_dbl = { 1, 2, 3, 4, 5, 6, 7 }; + struct cls_struct_align f_dbl = { 8, 9, 10, 11, 12, 13, 14 }; + struct cls_struct_align res_dbl; + cls_struct_type.size = 0; cls_struct_type.alignment = 0; cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.elements = cls_struct_fields; - struct cls_struct_align g_dbl = { 1, 2, 3, 4, 5, 6, 7 }; - struct cls_struct_align f_dbl = { 8, 9, 10, 11, 12, 13, 14 }; - struct cls_struct_align res_dbl; - cls_struct_fields[0] = &ffi_type_longdouble; cls_struct_fields[1] = &ffi_type_longdouble; cls_struct_fields[2] = &ffi_type_longdouble; diff --git a/libffi/testsuite/libffi.call/cls_align_pointer.c b/libffi/testsuite/libffi.call/cls_align_pointer.c index cbc4f95..8fbf36a 100644 --- a/libffi/testsuite/libffi.call/cls_align_pointer.c +++ b/libffi/testsuite/libffi.call/cls_align_pointer.c @@ -54,15 +54,15 @@ int main (void) ffi_type cls_struct_type; ffi_type* dbl_arg_types[5]; + struct cls_struct_align g_dbl = { 12, (void *)4951, 127 }; + struct cls_struct_align f_dbl = { 1, (void *)9320, 13 }; + struct cls_struct_align res_dbl; + cls_struct_type.size = 0; cls_struct_type.alignment = 0; cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.elements = cls_struct_fields; - struct cls_struct_align g_dbl = { 12, (void *)4951, 127 }; - struct cls_struct_align f_dbl = { 1, (void *)9320, 13 }; - struct cls_struct_align res_dbl; - cls_struct_fields[0] = &ffi_type_uchar; cls_struct_fields[1] = &ffi_type_pointer; cls_struct_fields[2] = &ffi_type_uchar; diff --git a/libffi/testsuite/libffi.call/cls_align_sint16.c b/libffi/testsuite/libffi.call/cls_align_sint16.c index 383ea41..039b874 100644 --- a/libffi/testsuite/libffi.call/cls_align_sint16.c +++ b/libffi/testsuite/libffi.call/cls_align_sint16.c @@ -50,15 +50,15 @@ int main (void) ffi_type cls_struct_type; ffi_type* dbl_arg_types[5]; + struct cls_struct_align g_dbl = { 12, 4951, 127 }; + struct cls_struct_align f_dbl = { 1, 9320, 13 }; + struct cls_struct_align res_dbl; + cls_struct_type.size = 0; cls_struct_type.alignment = 0; cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.elements = cls_struct_fields; - struct cls_struct_align g_dbl = { 12, 4951, 127 }; - struct cls_struct_align f_dbl = { 1, 9320, 13 }; - struct cls_struct_align res_dbl; - cls_struct_fields[0] = &ffi_type_uchar; cls_struct_fields[1] = &ffi_type_sshort; cls_struct_fields[2] = &ffi_type_uchar; diff --git a/libffi/testsuite/libffi.call/cls_align_sint32.c b/libffi/testsuite/libffi.call/cls_align_sint32.c index 705d78c..c96c6d1 100644 --- a/libffi/testsuite/libffi.call/cls_align_sint32.c +++ b/libffi/testsuite/libffi.call/cls_align_sint32.c @@ -50,15 +50,15 @@ int main (void) ffi_type cls_struct_type; ffi_type* dbl_arg_types[5]; + struct cls_struct_align g_dbl = { 12, 4951, 127 }; + struct cls_struct_align f_dbl = { 1, 9320, 13 }; + struct cls_struct_align res_dbl; + cls_struct_type.size = 0; cls_struct_type.alignment = 0; cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.elements = cls_struct_fields; - struct cls_struct_align g_dbl = { 12, 4951, 127 }; - struct cls_struct_align f_dbl = { 1, 9320, 13 }; - struct cls_struct_align res_dbl; - cls_struct_fields[0] = &ffi_type_uchar; cls_struct_fields[1] = &ffi_type_sint; cls_struct_fields[2] = &ffi_type_uchar; diff --git a/libffi/testsuite/libffi.call/cls_align_sint64.c b/libffi/testsuite/libffi.call/cls_align_sint64.c index 31d53af..9aa7bdd 100644 --- a/libffi/testsuite/libffi.call/cls_align_sint64.c +++ b/libffi/testsuite/libffi.call/cls_align_sint64.c @@ -51,15 +51,15 @@ int main (void) ffi_type cls_struct_type; ffi_type* dbl_arg_types[5]; + struct cls_struct_align g_dbl = { 12, 4951, 127 }; + struct cls_struct_align f_dbl = { 1, 9320, 13 }; + struct cls_struct_align res_dbl; + cls_struct_type.size = 0; cls_struct_type.alignment = 0; cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.elements = cls_struct_fields; - struct cls_struct_align g_dbl = { 12, 4951, 127 }; - struct cls_struct_align f_dbl = { 1, 9320, 13 }; - struct cls_struct_align res_dbl; - cls_struct_fields[0] = &ffi_type_uchar; cls_struct_fields[1] = &ffi_type_sint64; cls_struct_fields[2] = &ffi_type_uchar; diff --git a/libffi/testsuite/libffi.call/cls_align_uint16.c b/libffi/testsuite/libffi.call/cls_align_uint16.c index cb6b748..97620b7 100644 --- a/libffi/testsuite/libffi.call/cls_align_uint16.c +++ b/libffi/testsuite/libffi.call/cls_align_uint16.c @@ -50,15 +50,15 @@ int main (void) ffi_type cls_struct_type; ffi_type* dbl_arg_types[5]; + struct cls_struct_align g_dbl = { 12, 4951, 127 }; + struct cls_struct_align f_dbl = { 1, 9320, 13 }; + struct cls_struct_align res_dbl; + cls_struct_type.size = 0; cls_struct_type.alignment = 0; cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.elements = cls_struct_fields; - struct cls_struct_align g_dbl = { 12, 4951, 127 }; - struct cls_struct_align f_dbl = { 1, 9320, 13 }; - struct cls_struct_align res_dbl; - cls_struct_fields[0] = &ffi_type_uchar; cls_struct_fields[1] = &ffi_type_ushort; cls_struct_fields[2] = &ffi_type_uchar; diff --git a/libffi/testsuite/libffi.call/cls_align_uint32.c b/libffi/testsuite/libffi.call/cls_align_uint32.c index e453d3e..5766fad 100644 --- a/libffi/testsuite/libffi.call/cls_align_uint32.c +++ b/libffi/testsuite/libffi.call/cls_align_uint32.c @@ -50,15 +50,15 @@ int main (void) ffi_type cls_struct_type; ffi_type* dbl_arg_types[5]; + struct cls_struct_align g_dbl = { 12, 4951, 127 }; + struct cls_struct_align f_dbl = { 1, 9320, 13 }; + struct cls_struct_align res_dbl; + cls_struct_type.size = 0; cls_struct_type.alignment = 0; cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.elements = cls_struct_fields; - struct cls_struct_align g_dbl = { 12, 4951, 127 }; - struct cls_struct_align f_dbl = { 1, 9320, 13 }; - struct cls_struct_align res_dbl; - cls_struct_fields[0] = &ffi_type_uchar; cls_struct_fields[1] = &ffi_type_uint; cls_struct_fields[2] = &ffi_type_uchar; diff --git a/libffi/testsuite/libffi.call/cls_align_uint64.c b/libffi/testsuite/libffi.call/cls_align_uint64.c index 495c79f..a52cb89 100644 --- a/libffi/testsuite/libffi.call/cls_align_uint64.c +++ b/libffi/testsuite/libffi.call/cls_align_uint64.c @@ -52,15 +52,15 @@ int main (void) ffi_type cls_struct_type; ffi_type* dbl_arg_types[5]; + struct cls_struct_align g_dbl = { 12, 4951, 127 }; + struct cls_struct_align f_dbl = { 1, 9320, 13 }; + struct cls_struct_align res_dbl; + cls_struct_type.size = 0; cls_struct_type.alignment = 0; cls_struct_type.type = FFI_TYPE_STRUCT; cls_struct_type.elements = cls_struct_fields; - struct cls_struct_align g_dbl = { 12, 4951, 127 }; - struct cls_struct_align f_dbl = { 1, 9320, 13 }; - struct cls_struct_align res_dbl; - cls_struct_fields[0] = &ffi_type_uchar; cls_struct_fields[1] = &ffi_type_uint64; cls_struct_fields[2] = &ffi_type_uchar; diff --git a/libffi/testsuite/libffi.call/cls_dbls_struct.c b/libffi/testsuite/libffi.call/cls_dbls_struct.c index 660dabb..d663791 100644 --- a/libffi/testsuite/libffi.call/cls_dbls_struct.c +++ b/libffi/testsuite/libffi.call/cls_dbls_struct.c @@ -37,6 +37,8 @@ int main(int argc __UNUSED__, char** argv __UNUSED__) ffi_type ts1_type; ffi_type* ts1_type_elements[4]; + Dbls arg = { 1.0, 2.0 }; + ts1_type.size = 0; ts1_type.alignment = 0; ts1_type.type = FFI_TYPE_STRUCT; @@ -48,8 +50,6 @@ int main(int argc __UNUSED__, char** argv __UNUSED__) cl_arg_types[0] = &ts1_type; - Dbls arg = { 1.0, 2.0 }; - /* Initialize the cif */ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ffi_type_void, cl_arg_types) == FFI_OK); diff --git a/libffi/testsuite/libffi.call/cls_double_va.c b/libffi/testsuite/libffi.call/cls_double_va.c index 67e44a4..dbf2000 100644 --- a/libffi/testsuite/libffi.call/cls_double_va.c +++ b/libffi/testsuite/libffi.call/cls_double_va.c @@ -7,7 +7,6 @@ /* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */ /* { dg-output "" { xfail avr32*-*-* } } */ /* { dg-output "" { xfail mips-sgi-irix6* } } PR libffi/46660 */ -/* { dg-skip-if "" arm*-*-* { "-mfloat-abi=hard" } { "" } } */ #include "ffitest.h" diff --git a/libffi/testsuite/libffi.call/cls_longdouble_va.c b/libffi/testsuite/libffi.call/cls_longdouble_va.c index 6b8484a..4fa1ea2 100644 --- a/libffi/testsuite/libffi.call/cls_longdouble_va.c +++ b/libffi/testsuite/libffi.call/cls_longdouble_va.c @@ -7,7 +7,6 @@ /* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */ /* { dg-output "" { xfail avr32*-*-* x86_64-*-mingw* } } */ /* { dg-output "" { xfail mips-sgi-irix6* } } PR libffi/46660 */ -/* { dg-skip-if "" arm*-*-* { "-mfloat-abi=hard" } { "" } } */ #include "ffitest.h" diff --git a/libffi/testsuite/libffi.call/cls_pointer_stack.c b/libffi/testsuite/libffi.call/cls_pointer_stack.c index d631cf8..e31139e 100644 --- a/libffi/testsuite/libffi.call/cls_pointer_stack.c +++ b/libffi/testsuite/libffi.call/cls_pointer_stack.c @@ -28,11 +28,12 @@ void* cls_pointer_fn2(void* a1, void* a2) char trample6 = trample4 + ((char*)&a2)[1]; long double trample7 = (intptr_t)trample5 + (intptr_t)trample1; char trample8 = trample6 + trample2; + void* result; dummyVar = dummy_func(trample1, trample2, trample3, trample4, trample5, trample6, trample7, trample8); - void* result = (void*)((intptr_t)a1 + (intptr_t)a2); + result = (void*)((intptr_t)a1 + (intptr_t)a2); printf("0x%08x 0x%08x: 0x%08x\n", (unsigned int)(uintptr_t) a1, @@ -52,11 +53,12 @@ void* cls_pointer_fn1(void* a1, void* a2) char trample6 = trample4 + ((char*)&a2)[1]; long double trample7 = (intptr_t)trample5 + (intptr_t)trample1; char trample8 = trample6 + trample2; + void* result; dummyVar = dummy_func(trample1, trample2, trample3, trample4, trample5, trample6, trample7, trample8); - void* result = (void*)((intptr_t)a1 + (intptr_t)a2); + result = (void*)((intptr_t)a1 + (intptr_t)a2); printf("0x%08x 0x%08x: 0x%08x\n", (unsigned int)(intptr_t) a1, diff --git a/libffi/testsuite/libffi.call/cls_struct_va1.c b/libffi/testsuite/libffi.call/cls_struct_va1.c new file mode 100644 index 0000000..91772bd --- /dev/null +++ b/libffi/testsuite/libffi.call/cls_struct_va1.c @@ -0,0 +1,114 @@ +/* Area: ffi_call, closure_call + Purpose: Test doubles passed in variable argument lists. + Limitations: none. + PR: none. + Originator: Blake Chaffin 6/6/2007 */ + +/* { dg-do run } */ +/* { dg-output "" { xfail avr32*-*-* } } */ +#include "ffitest.h" + +struct small_tag +{ + unsigned char a; + unsigned char b; +}; + +struct large_tag +{ + unsigned a; + unsigned b; + unsigned c; + unsigned d; + unsigned e; +}; + +static void +test_fn (ffi_cif* cif __UNUSED__, void* resp, + void** args, void* userdata __UNUSED__) +{ + int n = *(int*)args[0]; + struct small_tag s1 = * (struct small_tag *) args[1]; + struct large_tag l1 = * (struct large_tag *) args[2]; + struct small_tag s2 = * (struct small_tag *) args[3]; + + printf ("%d %d %d %d %d %d %d %d %d %d\n", n, s1.a, s1.b, + l1.a, l1.b, l1.c, l1.d, l1.e, + s2.a, s2.b); + * (int*) resp = 42; +} + +int +main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc (sizeof (ffi_closure), &code); + ffi_type* arg_types[5]; + + ffi_arg res = 0; + + ffi_type s_type; + ffi_type *s_type_elements[3]; + + ffi_type l_type; + ffi_type *l_type_elements[6]; + + struct small_tag s1; + struct small_tag s2; + struct large_tag l1; + + int si; + + s_type.size = 0; + s_type.alignment = 0; + s_type.type = FFI_TYPE_STRUCT; + s_type.elements = s_type_elements; + + s_type_elements[0] = &ffi_type_uchar; + s_type_elements[1] = &ffi_type_uchar; + s_type_elements[2] = NULL; + + l_type.size = 0; + l_type.alignment = 0; + l_type.type = FFI_TYPE_STRUCT; + l_type.elements = l_type_elements; + + l_type_elements[0] = &ffi_type_uint; + l_type_elements[1] = &ffi_type_uint; + l_type_elements[2] = &ffi_type_uint; + l_type_elements[3] = &ffi_type_uint; + l_type_elements[4] = &ffi_type_uint; + l_type_elements[5] = NULL; + + arg_types[0] = &ffi_type_sint; + arg_types[1] = &s_type; + arg_types[2] = &l_type; + arg_types[3] = &s_type; + arg_types[4] = NULL; + + CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 4, &ffi_type_sint, + arg_types) == FFI_OK); + + si = 4; + s1.a = 5; + s1.b = 6; + + s2.a = 20; + s2.b = 21; + + l1.a = 10; + l1.b = 11; + l1.c = 12; + l1.d = 13; + l1.e = 14; + + CHECK(ffi_prep_closure_loc(pcl, &cif, test_fn, NULL, code) == FFI_OK); + + res = ((int (*)(int, ...))(code))(si, s1, l1, s2); + // { dg-output "4 5 6 10 11 12 13 14 20 21" } + printf("res: %d\n", (int) res); + // { dg-output "\nres: 42" } + + exit(0); +} diff --git a/libffi/testsuite/libffi.call/cls_uchar_va.c b/libffi/testsuite/libffi.call/cls_uchar_va.c new file mode 100644 index 0000000..19cd4f3 --- /dev/null +++ b/libffi/testsuite/libffi.call/cls_uchar_va.c @@ -0,0 +1,44 @@ +/* Area: closure_call + Purpose: Test anonymous unsigned char argument. + Limitations: none. + PR: none. + Originator: ARM Ltd. */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef unsigned char T; + +static void cls_ret_T_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) + { + *(T *)resp = *(T *)args[0]; + + printf("%d: %d %d\n", *(T *)resp, *(T *)args[0], *(T *)args[1]); + } + +typedef T (*cls_ret_T)(T, ...); + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + ffi_type * cl_arg_types[3]; + T res; + + cl_arg_types[0] = &ffi_type_uchar; + cl_arg_types[1] = &ffi_type_uchar; + cl_arg_types[2] = NULL; + + /* Initialize the cif */ + CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2, + &ffi_type_uchar, cl_arg_types) == FFI_OK); + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_T_fn, NULL, code) == FFI_OK); + res = ((((cls_ret_T)code)(67, 4))); + /* { dg-output "67: 67 4" } */ + printf("res: %d\n", res); + /* { dg-output "\nres: 67" } */ + exit(0); +} diff --git a/libffi/testsuite/libffi.call/cls_uint_va.c b/libffi/testsuite/libffi.call/cls_uint_va.c new file mode 100644 index 0000000..150fddd --- /dev/null +++ b/libffi/testsuite/libffi.call/cls_uint_va.c @@ -0,0 +1,45 @@ +/* Area: closure_call + Purpose: Test anonymous unsigned int argument. + Limitations: none. + PR: none. + Originator: ARM Ltd. */ + +/* { dg-do run } */ + +#include "ffitest.h" + +typedef unsigned int T; + +static void cls_ret_T_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) + { + *(T *)resp = *(T *)args[0]; + + printf("%d: %d %d\n", *(T *)resp, *(T *)args[0], *(T *)args[1]); + } + +typedef T (*cls_ret_T)(T, ...); + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + ffi_type * cl_arg_types[3]; + T res; + + cl_arg_types[0] = &ffi_type_uint; + cl_arg_types[1] = &ffi_type_uint; + cl_arg_types[2] = NULL; + + /* Initialize the cif */ + CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2, + &ffi_type_uint, cl_arg_types) == FFI_OK); + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_T_fn, NULL, code) == FFI_OK); + res = ((((cls_ret_T)code)(67, 4))); + /* { dg-output "67: 67 4" } */ + printf("res: %d\n", res); + /* { dg-output "\nres: 67" } */ + exit(0); +} diff --git a/libffi/testsuite/libffi.call/cls_ulong_va.c b/libffi/testsuite/libffi.call/cls_ulong_va.c new file mode 100644 index 0000000..0315082 --- /dev/null +++ b/libffi/testsuite/libffi.call/cls_ulong_va.c @@ -0,0 +1,45 @@ +/* Area: closure_call + Purpose: Test anonymous unsigned long argument. + Limitations: none. + PR: none. + Originator: ARM Ltd. */ + +/* { dg-do run } */ + +#include "ffitest.h" + +typedef unsigned long T; + +static void cls_ret_T_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) + { + *(T *)resp = *(T *)args[0]; + + printf("%ld: %ld %ld\n", *(T *)resp, *(T *)args[0], *(T *)args[1]); + } + +typedef T (*cls_ret_T)(T, ...); + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + ffi_type * cl_arg_types[3]; + T res; + + cl_arg_types[0] = &ffi_type_ulong; + cl_arg_types[1] = &ffi_type_ulong; + cl_arg_types[2] = NULL; + + /* Initialize the cif */ + CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2, + &ffi_type_ulong, cl_arg_types) == FFI_OK); + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_T_fn, NULL, code) == FFI_OK); + res = ((((cls_ret_T)code)(67, 4))); + /* { dg-output "67: 67 4" } */ + printf("res: %ld\n", res); + /* { dg-output "\nres: 67" } */ + exit(0); +} diff --git a/libffi/testsuite/libffi.call/cls_ushort_va.c b/libffi/testsuite/libffi.call/cls_ushort_va.c new file mode 100644 index 0000000..b2b5a3b --- /dev/null +++ b/libffi/testsuite/libffi.call/cls_ushort_va.c @@ -0,0 +1,44 @@ +/* Area: closure_call + Purpose: Test anonymous unsigned short argument. + Limitations: none. + PR: none. + Originator: ARM Ltd. */ + +/* { dg-do run } */ +#include "ffitest.h" + +typedef unsigned short T; + +static void cls_ret_T_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, + void* userdata __UNUSED__) + { + *(T *)resp = *(T *)args[0]; + + printf("%d: %d %d\n", *(T *)resp, *(T *)args[0], *(T *)args[1]); + } + +typedef T (*cls_ret_T)(T, ...); + +int main (void) +{ + ffi_cif cif; + void *code; + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); + ffi_type * cl_arg_types[3]; + T res; + + cl_arg_types[0] = &ffi_type_ushort; + cl_arg_types[1] = &ffi_type_ushort; + cl_arg_types[2] = NULL; + + /* Initialize the cif */ + CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2, + &ffi_type_ushort, cl_arg_types) == FFI_OK); + + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_T_fn, NULL, code) == FFI_OK); + res = ((((cls_ret_T)code)(67, 4))); + /* { dg-output "67: 67 4" } */ + printf("res: %d\n", res); + /* { dg-output "\nres: 67" } */ + exit(0); +} diff --git a/libffi/testsuite/libffi.call/err_bad_typedef.c b/libffi/testsuite/libffi.call/err_bad_typedef.c index 2539273..bf60161 100644 --- a/libffi/testsuite/libffi.call/err_bad_typedef.c +++ b/libffi/testsuite/libffi.call/err_bad_typedef.c @@ -13,10 +13,10 @@ int main (void) ffi_cif cif; ffi_type* arg_types[1]; - arg_types[0] = NULL; - ffi_type badType = ffi_type_void; + arg_types[0] = NULL; + badType.size = 0; CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 0, &badType, diff --git a/libffi/testsuite/libffi.call/fastthis1_win32.c b/libffi/testsuite/libffi.call/fastthis1_win32.c index b3c4c73..cbc4724 100644 --- a/libffi/testsuite/libffi.call/fastthis1_win32.c +++ b/libffi/testsuite/libffi.call/fastthis1_win32.c @@ -8,7 +8,7 @@ #include "ffitest.h" -static size_t __attribute__((fastcall)) my_fastcall_f(char *s, float a) +static size_t __FASTCALL__ my_fastcall_f(char *s, float a) { return (size_t) ((int) strlen(s) + (int) a); } diff --git a/libffi/testsuite/libffi.call/fastthis2_win32.c b/libffi/testsuite/libffi.call/fastthis2_win32.c index f148a12..7bdd0e1 100644 --- a/libffi/testsuite/libffi.call/fastthis2_win32.c +++ b/libffi/testsuite/libffi.call/fastthis2_win32.c @@ -8,7 +8,7 @@ #include "ffitest.h" -static size_t __attribute__((fastcall)) my_fastcall_f(float a, char *s) +static size_t __FASTCALL__ my_fastcall_f(float a, char *s) { return (size_t) ((int) strlen(s) + (int) a); } diff --git a/libffi/testsuite/libffi.call/fastthis3_win32.c b/libffi/testsuite/libffi.call/fastthis3_win32.c index 5cf82bb..b5d606d 100644 --- a/libffi/testsuite/libffi.call/fastthis3_win32.c +++ b/libffi/testsuite/libffi.call/fastthis3_win32.c @@ -8,7 +8,7 @@ #include "ffitest.h" -static size_t __attribute__((fastcall)) my_fastcall_f(float a, char *s, int i) +static size_t __FASTCALL__ my_fastcall_f(float a, char *s, int i) { return (size_t) ((int) strlen(s) + (int) a + i); } diff --git a/libffi/testsuite/libffi.call/ffitest.h b/libffi/testsuite/libffi.call/ffitest.h index 0e95e16..d81d4da 100644 --- a/libffi/testsuite/libffi.call/ffitest.h +++ b/libffi/testsuite/libffi.call/ffitest.h @@ -25,6 +25,14 @@ #define __UNUSED__ #endif +/* Define __FASTCALL__ so that other compilers than gcc can run the tests. */ +#undef __FASTCALL__ +#if defined _MSC_VER +#define __FASTCALL__ __fastcall +#else +#define __FASTCALL__ __attribute__((fastcall)) +#endif + /* Prefer MAP_ANON(YMOUS) to /dev/zero, since we don't need to keep a file open. */ #ifdef HAVE_MMAP_ANON @@ -110,6 +118,15 @@ #endif #endif +/* MSVC kludge. */ +#if defined _MSC_VER +#define PRIuPTR "lu" +#define PRIu8 "u" +#define PRId8 "d" +#define PRIu64 "I64u" +#define PRId64 "I64d" +#endif + #ifdef USING_MMAP static inline void * allocate_mmap (size_t size) diff --git a/libffi/testsuite/libffi.call/float_va.c b/libffi/testsuite/libffi.call/float_va.c index 2039ae5..aae158e 100644 --- a/libffi/testsuite/libffi.call/float_va.c +++ b/libffi/testsuite/libffi.call/float_va.c @@ -25,18 +25,18 @@ double float_va_fn(unsigned int x, double y,...) total+=(double)x; total+=y; - printf("%u: %.1lf :", x, y); + printf("%u: %.1f :", x, y); va_start(ap, y); for(i=0;iui == 556); + CHECK(ts1_result->d == 3.14159 - 1); + + free (ts1_result); + exit(0); +} diff --git a/libffi/testsuite/libffi.call/va_1.c b/libffi/testsuite/libffi.call/va_1.c new file mode 100644 index 0000000..5c7cce9 --- /dev/null +++ b/libffi/testsuite/libffi.call/va_1.c @@ -0,0 +1,196 @@ +/* Area: ffi_call + Purpose: Test passing struct in variable argument lists. + Limitations: none. + PR: none. + Originator: ARM Ltd. */ + +/* { dg-do run } */ +/* { dg-output "" { xfail avr32*-*-* x86_64-*-*-* } } */ + +#include "ffitest.h" +#include + +struct small_tag +{ + unsigned char a; + unsigned char b; +}; + +struct large_tag +{ + unsigned a; + unsigned b; + unsigned c; + unsigned d; + unsigned e; +}; + +static int +test_fn (int n, ...) +{ + va_list ap; + struct small_tag s1; + struct small_tag s2; + struct large_tag l; + unsigned char uc; + signed char sc; + unsigned short us; + signed short ss; + unsigned int ui; + signed int si; + unsigned long ul; + signed long sl; + float f; + double d; + + va_start (ap, n); + s1 = va_arg (ap, struct small_tag); + l = va_arg (ap, struct large_tag); + s2 = va_arg (ap, struct small_tag); + + uc = va_arg (ap, unsigned); + sc = va_arg (ap, signed); + + us = va_arg (ap, unsigned); + ss = va_arg (ap, signed); + + ui = va_arg (ap, unsigned int); + si = va_arg (ap, signed int); + + ul = va_arg (ap, unsigned long); + sl = va_arg (ap, signed long); + + f = va_arg (ap, double); /* C standard promotes float->double + when anonymous */ + d = va_arg (ap, double); + + printf ("%u %u %u %u %u %u %u %u %u uc=%u sc=%d %u %d %u %d %lu %ld %f %f\n", + s1.a, s1.b, l.a, l.b, l.c, l.d, l.e, + s2.a, s2.b, + uc, sc, + us, ss, + ui, si, + ul, sl, + f, d); + va_end (ap); + return n + 1; +} + +int +main (void) +{ + ffi_cif cif; + void* args[15]; + ffi_type* arg_types[15]; + + ffi_type s_type; + ffi_type *s_type_elements[3]; + + ffi_type l_type; + ffi_type *l_type_elements[6]; + + struct small_tag s1; + struct small_tag s2; + struct large_tag l1; + + int n; + int res; + + unsigned char uc; + signed char sc; + unsigned short us; + signed short ss; + unsigned int ui; + signed int si; + unsigned long ul; + signed long sl; + double d1; + double f1; + + s_type.size = 0; + s_type.alignment = 0; + s_type.type = FFI_TYPE_STRUCT; + s_type.elements = s_type_elements; + + s_type_elements[0] = &ffi_type_uchar; + s_type_elements[1] = &ffi_type_uchar; + s_type_elements[2] = NULL; + + l_type.size = 0; + l_type.alignment = 0; + l_type.type = FFI_TYPE_STRUCT; + l_type.elements = l_type_elements; + + l_type_elements[0] = &ffi_type_uint; + l_type_elements[1] = &ffi_type_uint; + l_type_elements[2] = &ffi_type_uint; + l_type_elements[3] = &ffi_type_uint; + l_type_elements[4] = &ffi_type_uint; + l_type_elements[5] = NULL; + + arg_types[0] = &ffi_type_sint; + arg_types[1] = &s_type; + arg_types[2] = &l_type; + arg_types[3] = &s_type; + arg_types[4] = &ffi_type_uint; + arg_types[5] = &ffi_type_sint; + arg_types[6] = &ffi_type_uint; + arg_types[7] = &ffi_type_sint; + arg_types[8] = &ffi_type_uint; + arg_types[9] = &ffi_type_sint; + arg_types[10] = &ffi_type_ulong; + arg_types[11] = &ffi_type_slong; + arg_types[12] = &ffi_type_double; + arg_types[13] = &ffi_type_double; + arg_types[14] = NULL; + + CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 14, &ffi_type_sint, arg_types) == FFI_OK); + + s1.a = 5; + s1.b = 6; + + l1.a = 10; + l1.b = 11; + l1.c = 12; + l1.d = 13; + l1.e = 14; + + s2.a = 7; + s2.b = 8; + + n = 41; + + uc = 9; + sc = 10; + us = 11; + ss = 12; + ui = 13; + si = 14; + ul = 15; + sl = 16; + f1 = 2.12; + d1 = 3.13; + + args[0] = &n; + args[1] = &s1; + args[2] = &l1; + args[3] = &s2; + args[4] = &uc; + args[5] = ≻ + args[6] = &us; + args[7] = &ss; + args[8] = &ui; + args[9] = &si; + args[10] = &ul; + args[11] = &sl; + args[12] = &f1; + args[13] = &d1; + args[14] = NULL; + + ffi_call(&cif, FFI_FN(test_fn), &res, args); + /* { dg-output "5 6 10 11 12 13 14 7 8 uc=9 sc=10 11 12 13 14 15 16 2.120000 3.130000" } */ + printf("res: %d\n", (int) res); + /* { dg-output "\nres: 42" } */ + + return 0; +} diff --git a/libffi/testsuite/libffi.call/va_struct1.c b/libffi/testsuite/libffi.call/va_struct1.c new file mode 100644 index 0000000..11d1f10 --- /dev/null +++ b/libffi/testsuite/libffi.call/va_struct1.c @@ -0,0 +1,121 @@ +/* Area: ffi_call + Purpose: Test passing struct in variable argument lists. + Limitations: none. + PR: none. + Originator: ARM Ltd. */ + +/* { dg-do run } */ +/* { dg-output "" { xfail avr32*-*-* } } */ + +#include "ffitest.h" +#include + +struct small_tag +{ + unsigned char a; + unsigned char b; +}; + +struct large_tag +{ + unsigned a; + unsigned b; + unsigned c; + unsigned d; + unsigned e; +}; + +static int +test_fn (int n, ...) +{ + va_list ap; + struct small_tag s1; + struct small_tag s2; + struct large_tag l; + + va_start (ap, n); + s1 = va_arg (ap, struct small_tag); + l = va_arg (ap, struct large_tag); + s2 = va_arg (ap, struct small_tag); + printf ("%u %u %u %u %u %u %u %u %u\n", s1.a, s1.b, l.a, l.b, l.c, l.d, l.e, + s2.a, s2.b); + va_end (ap); + return n + 1; +} + +int +main (void) +{ + ffi_cif cif; + void* args[5]; + ffi_type* arg_types[5]; + + ffi_type s_type; + ffi_type *s_type_elements[3]; + + ffi_type l_type; + ffi_type *l_type_elements[6]; + + struct small_tag s1; + struct small_tag s2; + struct large_tag l1; + + int n; + int res; + + s_type.size = 0; + s_type.alignment = 0; + s_type.type = FFI_TYPE_STRUCT; + s_type.elements = s_type_elements; + + s_type_elements[0] = &ffi_type_uchar; + s_type_elements[1] = &ffi_type_uchar; + s_type_elements[2] = NULL; + + l_type.size = 0; + l_type.alignment = 0; + l_type.type = FFI_TYPE_STRUCT; + l_type.elements = l_type_elements; + + l_type_elements[0] = &ffi_type_uint; + l_type_elements[1] = &ffi_type_uint; + l_type_elements[2] = &ffi_type_uint; + l_type_elements[3] = &ffi_type_uint; + l_type_elements[4] = &ffi_type_uint; + l_type_elements[5] = NULL; + + arg_types[0] = &ffi_type_sint; + arg_types[1] = &s_type; + arg_types[2] = &l_type; + arg_types[3] = &s_type; + arg_types[4] = NULL; + + CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 4, &ffi_type_sint, arg_types) == FFI_OK); + + s1.a = 5; + s1.b = 6; + + l1.a = 10; + l1.b = 11; + l1.c = 12; + l1.d = 13; + l1.e = 14; + + s2.a = 7; + s2.b = 8; + + n = 41; + + args[0] = &n; + args[1] = &s1; + args[2] = &l1; + args[3] = &s2; + args[4] = NULL; + + ffi_call(&cif, FFI_FN(test_fn), &res, args); + /* { dg-output "5 6 10 11 12 13 14 7 8" } */ + printf("res: %d\n", (int) res); + /* { dg-output "\nres: 42" } */ + + return 0; +} diff --git a/libffi/testsuite/libffi.call/va_struct2.c b/libffi/testsuite/libffi.call/va_struct2.c new file mode 100644 index 0000000..56f5b9c --- /dev/null +++ b/libffi/testsuite/libffi.call/va_struct2.c @@ -0,0 +1,123 @@ +/* Area: ffi_call + Purpose: Test passing struct in variable argument lists. + Limitations: none. + PR: none. + Originator: ARM Ltd. */ + +/* { dg-do run } */ +/* { dg-output "" { xfail avr32*-*-* } } */ + +#include "ffitest.h" +#include + +struct small_tag +{ + unsigned char a; + unsigned char b; +}; + +struct large_tag +{ + unsigned a; + unsigned b; + unsigned c; + unsigned d; + unsigned e; +}; + +static struct small_tag +test_fn (int n, ...) +{ + va_list ap; + struct small_tag s1; + struct small_tag s2; + struct large_tag l; + + va_start (ap, n); + s1 = va_arg (ap, struct small_tag); + l = va_arg (ap, struct large_tag); + s2 = va_arg (ap, struct small_tag); + printf ("%u %u %u %u %u %u %u %u %u\n", s1.a, s1.b, l.a, l.b, l.c, l.d, l.e, + s2.a, s2.b); + va_end (ap); + s1.a += s2.a; + s1.b += s2.b; + return s1; +} + +int +main (void) +{ + ffi_cif cif; + void* args[5]; + ffi_type* arg_types[5]; + + ffi_type s_type; + ffi_type *s_type_elements[3]; + + ffi_type l_type; + ffi_type *l_type_elements[6]; + + struct small_tag s1; + struct small_tag s2; + struct large_tag l1; + + int n; + struct small_tag res; + + s_type.size = 0; + s_type.alignment = 0; + s_type.type = FFI_TYPE_STRUCT; + s_type.elements = s_type_elements; + + s_type_elements[0] = &ffi_type_uchar; + s_type_elements[1] = &ffi_type_uchar; + s_type_elements[2] = NULL; + + l_type.size = 0; + l_type.alignment = 0; + l_type.type = FFI_TYPE_STRUCT; + l_type.elements = l_type_elements; + + l_type_elements[0] = &ffi_type_uint; + l_type_elements[1] = &ffi_type_uint; + l_type_elements[2] = &ffi_type_uint; + l_type_elements[3] = &ffi_type_uint; + l_type_elements[4] = &ffi_type_uint; + l_type_elements[5] = NULL; + + arg_types[0] = &ffi_type_sint; + arg_types[1] = &s_type; + arg_types[2] = &l_type; + arg_types[3] = &s_type; + arg_types[4] = NULL; + + CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 4, &s_type, arg_types) == FFI_OK); + + s1.a = 5; + s1.b = 6; + + l1.a = 10; + l1.b = 11; + l1.c = 12; + l1.d = 13; + l1.e = 14; + + s2.a = 7; + s2.b = 8; + + n = 41; + + args[0] = &n; + args[1] = &s1; + args[2] = &l1; + args[3] = &s2; + args[4] = NULL; + + ffi_call(&cif, FFI_FN(test_fn), &res, args); + /* { dg-output "5 6 10 11 12 13 14 7 8" } */ + printf("res: %d %d\n", res.a, res.b); + /* { dg-output "\nres: 12 14" } */ + + return 0; +} diff --git a/libffi/testsuite/libffi.call/va_struct3.c b/libffi/testsuite/libffi.call/va_struct3.c new file mode 100644 index 0000000..9a27e7f --- /dev/null +++ b/libffi/testsuite/libffi.call/va_struct3.c @@ -0,0 +1,125 @@ +/* Area: ffi_call + Purpose: Test passing struct in variable argument lists. + Limitations: none. + PR: none. + Originator: ARM Ltd. */ + +/* { dg-do run } */ +/* { dg-output "" { xfail avr32*-*-* } } */ + +#include "ffitest.h" +#include + +struct small_tag +{ + unsigned char a; + unsigned char b; +}; + +struct large_tag +{ + unsigned a; + unsigned b; + unsigned c; + unsigned d; + unsigned e; +}; + +static struct large_tag +test_fn (int n, ...) +{ + va_list ap; + struct small_tag s1; + struct small_tag s2; + struct large_tag l; + + va_start (ap, n); + s1 = va_arg (ap, struct small_tag); + l = va_arg (ap, struct large_tag); + s2 = va_arg (ap, struct small_tag); + printf ("%u %u %u %u %u %u %u %u %u\n", s1.a, s1.b, l.a, l.b, l.c, l.d, l.e, + s2.a, s2.b); + va_end (ap); + l.a += s1.a; + l.b += s1.b; + l.c += s2.a; + l.d += s2.b; + return l; +} + +int +main (void) +{ + ffi_cif cif; + void* args[5]; + ffi_type* arg_types[5]; + + ffi_type s_type; + ffi_type *s_type_elements[3]; + + ffi_type l_type; + ffi_type *l_type_elements[6]; + + struct small_tag s1; + struct small_tag s2; + struct large_tag l1; + + int n; + struct large_tag res; + + s_type.size = 0; + s_type.alignment = 0; + s_type.type = FFI_TYPE_STRUCT; + s_type.elements = s_type_elements; + + s_type_elements[0] = &ffi_type_uchar; + s_type_elements[1] = &ffi_type_uchar; + s_type_elements[2] = NULL; + + l_type.size = 0; + l_type.alignment = 0; + l_type.type = FFI_TYPE_STRUCT; + l_type.elements = l_type_elements; + + l_type_elements[0] = &ffi_type_uint; + l_type_elements[1] = &ffi_type_uint; + l_type_elements[2] = &ffi_type_uint; + l_type_elements[3] = &ffi_type_uint; + l_type_elements[4] = &ffi_type_uint; + l_type_elements[5] = NULL; + + arg_types[0] = &ffi_type_sint; + arg_types[1] = &s_type; + arg_types[2] = &l_type; + arg_types[3] = &s_type; + arg_types[4] = NULL; + + CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 4, &l_type, arg_types) == FFI_OK); + + s1.a = 5; + s1.b = 6; + + l1.a = 10; + l1.b = 11; + l1.c = 12; + l1.d = 13; + l1.e = 14; + + s2.a = 7; + s2.b = 8; + + n = 41; + + args[0] = &n; + args[1] = &s1; + args[2] = &l1; + args[3] = &s2; + args[4] = NULL; + + ffi_call(&cif, FFI_FN(test_fn), &res, args); + /* { dg-output "5 6 10 11 12 13 14 7 8" } */ + printf("res: %d %d %d %d %d\n", res.a, res.b, res.c, res.d, res.e); + /* { dg-output "\nres: 15 17 19 21 14" } */ + + return 0; +} -- cgit v1.1