ffi 1.9.23 → 1.9.24

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +66 -0
  3. data/Rakefile +1 -1
  4. data/ext/ffi_c/Call.c +5 -2
  5. data/ext/ffi_c/Function.c +8 -5
  6. data/ext/ffi_c/Thread.c +1 -0
  7. data/ext/ffi_c/extconf.rb +1 -0
  8. data/ext/ffi_c/libffi/.appveyor.yml +6 -4
  9. data/ext/ffi_c/libffi/.github/issue_template.md +10 -0
  10. data/ext/ffi_c/libffi/.gitignore +2 -0
  11. data/ext/ffi_c/libffi/.travis.yml +20 -16
  12. data/ext/ffi_c/libffi/.travis/ar-lib +270 -0
  13. data/ext/ffi_c/libffi/.travis/build.sh +34 -0
  14. data/ext/ffi_c/libffi/.travis/compile +351 -0
  15. data/ext/ffi_c/libffi/.travis/install.sh +11 -3
  16. data/ext/ffi_c/libffi/.travis/moxie-sim.exp +60 -0
  17. data/ext/ffi_c/libffi/.travis/site.exp +18 -0
  18. data/ext/ffi_c/libffi/LICENSE-BUILDTOOLS +352 -0
  19. data/ext/ffi_c/libffi/Makefile.am +4 -45
  20. data/ext/ffi_c/libffi/{README → README.md} +237 -230
  21. data/ext/ffi_c/libffi/configure.ac +10 -8
  22. data/ext/ffi_c/libffi/configure.host +5 -0
  23. data/ext/ffi_c/libffi/include/ffi.h.in +48 -26
  24. data/ext/ffi_c/libffi/include/ffi_common.h +2 -0
  25. data/ext/ffi_c/libffi/m4/ax_append_flag.m4 +18 -16
  26. data/ext/ffi_c/libffi/m4/ax_cc_maxopt.m4 +21 -8
  27. data/ext/ffi_c/libffi/m4/ax_cflags_warn_all.m4 +4 -4
  28. data/ext/ffi_c/libffi/m4/ax_check_compile_flag.m4 +9 -7
  29. data/ext/ffi_c/libffi/m4/ax_compiler_vendor.m4 +8 -5
  30. data/ext/ffi_c/libffi/m4/ax_configure_args.m4 +5 -5
  31. data/ext/ffi_c/libffi/m4/ax_enable_builddir.m4 +7 -6
  32. data/ext/ffi_c/libffi/m4/ax_gcc_archflag.m4 +99 -61
  33. data/ext/ffi_c/libffi/m4/ax_gcc_x86_cpuid.m4 +18 -8
  34. data/ext/ffi_c/libffi/m4/ax_require_defined.m4 +37 -0
  35. data/ext/ffi_c/libffi/msvcc.sh +82 -14
  36. data/ext/ffi_c/libffi/src/aarch64/ffi.c +8 -31
  37. data/ext/ffi_c/libffi/src/closures.c +31 -1
  38. data/ext/ffi_c/libffi/src/ia64/ffi.c +24 -6
  39. data/ext/ffi_c/libffi/src/ia64/ffitarget.h +2 -1
  40. data/ext/ffi_c/libffi/src/ia64/unix.S +6 -1
  41. data/ext/ffi_c/libffi/src/mips/ffi.c +29 -12
  42. data/ext/ffi_c/libffi/src/mips/ffitarget.h +7 -12
  43. data/ext/ffi_c/libffi/src/moxie/eabi.S +1 -1
  44. data/ext/ffi_c/libffi/src/moxie/ffi.c +18 -5
  45. data/ext/ffi_c/libffi/src/powerpc/ffi_linux64.c +45 -16
  46. data/ext/ffi_c/libffi/src/riscv/ffi.c +445 -0
  47. data/ext/ffi_c/libffi/src/riscv/ffitarget.h +68 -0
  48. data/ext/ffi_c/libffi/src/riscv/sysv.S +214 -0
  49. data/ext/ffi_c/libffi/src/types.c +3 -1
  50. data/ext/ffi_c/libffi/src/x86/ffi.c +18 -0
  51. data/ext/ffi_c/libffi/src/x86/ffi64.c +15 -9
  52. data/ext/ffi_c/libffi/src/x86/ffitarget.h +8 -2
  53. data/ext/ffi_c/libffi/src/x86/ffiw64.c +30 -9
  54. data/ext/ffi_c/libffi/src/xtensa/sysv.S +6 -1
  55. data/ext/ffi_c/libffi/testsuite/Makefile.am +108 -77
  56. data/ext/ffi_c/libffi/testsuite/lib/libffi.exp +195 -5
  57. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/Makefile +28 -0
  58. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/README +78 -0
  59. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/alignof.h +50 -0
  60. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/bhaible.exp +58 -0
  61. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/test-call.c +1745 -0
  62. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/test-callback.c +2885 -0
  63. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/testcases.c +743 -0
  64. data/ext/ffi_c/libffi/testsuite/libffi.call/align_stdcall.c +46 -0
  65. data/ext/ffi_c/libffi/testsuite/libffi.call/call.exp +14 -1
  66. data/ext/ffi_c/libffi/testsuite/libffi.call/ffitest.h +3 -1
  67. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct10.c +1 -0
  68. data/ext/ffi_c/libffi/testsuite/libffi.call/struct10.c +57 -0
  69. data/ext/ffi_c/libffi/testsuite/libffi.call/unwindtest.cc +1 -1
  70. data/ext/ffi_c/libffi/testsuite/libffi.call/unwindtest_ffi_call.cc +1 -1
  71. data/lib/ffi/library.rb +2 -4
  72. data/lib/ffi/platform/mips64-linux/types.conf +104 -0
  73. data/lib/ffi/platform/mipsisa32r6-linux/types.conf +102 -0
  74. data/lib/ffi/platform/mipsisa32r6el-linux/types.conf +102 -0
  75. data/lib/ffi/platform/mipsisa64r6-linux/types.conf +104 -0
  76. data/lib/ffi/platform/mipsisa64r6el-linux/types.conf +104 -0
  77. data/lib/ffi/version.rb +1 -1
  78. metadata +29 -3
@@ -0,0 +1,68 @@
1
+ /* -----------------------------------------------------------------*-C-*-
2
+ ffitarget.h - 2014 Michael Knyszek
3
+
4
+ Target configuration macros for RISC-V.
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining
7
+ a copy of this software and associated documentation files (the
8
+ ``Software''), to deal in the Software without restriction, including
9
+ without limitation the rights to use, copy, modify, merge, publish,
10
+ distribute, sublicense, and/or sell copies of the Software, and to
11
+ permit persons to whom the Software is furnished to do so, subject to
12
+ the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be included
15
+ in all copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
18
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24
+ DEALINGS IN THE SOFTWARE.
25
+
26
+ ----------------------------------------------------------------------- */
27
+
28
+ #ifndef LIBFFI_TARGET_H
29
+ #define LIBFFI_TARGET_H
30
+
31
+ #ifndef LIBFFI_H
32
+ #error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
33
+ #endif
34
+
35
+ #ifndef __riscv
36
+ #error "libffi was configured for a RISC-V target but this does not appear to be a RISC-V compiler."
37
+ #endif
38
+
39
+ #ifndef LIBFFI_ASM
40
+
41
+ typedef unsigned long ffi_arg;
42
+ typedef signed long ffi_sarg;
43
+
44
+ /* FFI_UNUSED_NN and riscv_unused are to maintain ABI compatibility with a
45
+ distributed Berkeley patch from 2014, and can be removed at SONAME bump */
46
+ typedef enum ffi_abi {
47
+ FFI_FIRST_ABI = 0,
48
+ FFI_SYSV,
49
+ FFI_UNUSED_1,
50
+ FFI_UNUSED_2,
51
+ FFI_UNUSED_3,
52
+ FFI_LAST_ABI,
53
+
54
+ FFI_DEFAULT_ABI = FFI_SYSV
55
+ } ffi_abi;
56
+
57
+ #endif /* LIBFFI_ASM */
58
+
59
+ /* ---- Definitions for closures ----------------------------------------- */
60
+
61
+ #define FFI_CLOSURES 1
62
+ #define FFI_TRAMPOLINE_SIZE 24
63
+ #define FFI_NATIVE_RAW_API 0
64
+ #define FFI_EXTRA_CIF_FIELDS unsigned riscv_nfixedargs; unsigned riscv_unused;
65
+ #define FFI_TARGET_SPECIFIC_VARIADIC
66
+
67
+ #endif
68
+
@@ -0,0 +1,214 @@
1
+ /* -----------------------------------------------------------------------
2
+ ffi.c - Copyright (c) 2015 Michael Knyszek <mknyszek@berkeley.edu>
3
+ 2015 Andrew Waterman <waterman@cs.berkeley.edu>
4
+ 2018 Stef O'Rear <sorear2@gmail.com>
5
+
6
+ RISC-V Foreign Function Interface
7
+
8
+ Permission is hereby granted, free of charge, to any person obtaining
9
+ a copy of this software and associated documentation files (the
10
+ ``Software''), to deal in the Software without restriction, including
11
+ without limitation the rights to use, copy, modify, merge, publish,
12
+ distribute, sublicense, and/or sell copies of the Software, and to
13
+ permit persons to whom the Software is furnished to do so, subject to
14
+ the following conditions:
15
+
16
+ The above copyright notice and this permission notice shall be included
17
+ in all copies or substantial portions of the Software.
18
+
19
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
20
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
23
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26
+ DEALINGS IN THE SOFTWARE.
27
+ ----------------------------------------------------------------------- */
28
+
29
+ #define LIBFFI_ASM
30
+ #include <fficonfig.h>
31
+ #include <ffi.h>
32
+
33
+ /* Define aliases so that we can handle all ABIs uniformly */
34
+
35
+ #if __SIZEOF_POINTER__ == 8
36
+ #define PTRS 8
37
+ #define LARG ld
38
+ #define SARG sd
39
+ #else
40
+ #define PTRS 4
41
+ #define LARG lw
42
+ #define SARG sw
43
+ #endif
44
+
45
+ #if __riscv_float_abi_double
46
+ #define FLTS 8
47
+ #define FLARG fld
48
+ #define FSARG fsd
49
+ #elif __riscv_float_abi_single
50
+ #define FLTS 4
51
+ #define FLARG flw
52
+ #define FSARG fsw
53
+ #else
54
+ #define FLTS 0
55
+ #endif
56
+
57
+ #define fp s0
58
+
59
+ .text
60
+ .globl ffi_call_asm
61
+ .type ffi_call_asm, @function
62
+ .hidden ffi_call_asm
63
+ /*
64
+ struct call_context {
65
+ floatreg fa[8];
66
+ intreg a[8];
67
+ intreg pad[rv32 ? 2 : 0];
68
+ intreg save_fp, save_ra;
69
+ }
70
+ void ffi_call_asm(size_t *stackargs, struct call_context *regargs,
71
+ void (*fn)(void));
72
+ */
73
+
74
+ #define FRAME_LEN (8 * FLTS + 8 * PTRS + 16)
75
+
76
+ ffi_call_asm:
77
+ .cfi_startproc
78
+
79
+ /*
80
+ We are NOT going to set up an ordinary stack frame. In order to pass
81
+ the stacked args to the called function, we adjust our stack pointer to
82
+ a0, which is in the _caller's_ alloca area. We establish our own stack
83
+ frame at the end of the call_context.
84
+
85
+ Anything below the arguments will be freed at this point, although we
86
+ preserve the call_context so that it can be read back in the caller.
87
+ */
88
+
89
+ .cfi_def_cfa 11, FRAME_LEN # interim CFA based on a1
90
+ SARG fp, FRAME_LEN - 2*PTRS(a1)
91
+ .cfi_offset 8, -2*PTRS
92
+ SARG ra, FRAME_LEN - 1*PTRS(a1)
93
+ .cfi_offset 1, -1*PTRS
94
+
95
+ addi fp, a1, FRAME_LEN
96
+ mv sp, a0
97
+ .cfi_def_cfa 8, 0 # our frame is fully set up
98
+
99
+ # Load arguments
100
+ mv t1, a2
101
+
102
+ #if FLTS
103
+ FLARG fa0, -FRAME_LEN+0*FLTS(fp)
104
+ FLARG fa1, -FRAME_LEN+1*FLTS(fp)
105
+ FLARG fa2, -FRAME_LEN+2*FLTS(fp)
106
+ FLARG fa3, -FRAME_LEN+3*FLTS(fp)
107
+ FLARG fa4, -FRAME_LEN+4*FLTS(fp)
108
+ FLARG fa5, -FRAME_LEN+5*FLTS(fp)
109
+ FLARG fa6, -FRAME_LEN+6*FLTS(fp)
110
+ FLARG fa7, -FRAME_LEN+7*FLTS(fp)
111
+ #endif
112
+
113
+ LARG a0, -FRAME_LEN+8*FLTS+0*PTRS(fp)
114
+ LARG a1, -FRAME_LEN+8*FLTS+1*PTRS(fp)
115
+ LARG a2, -FRAME_LEN+8*FLTS+2*PTRS(fp)
116
+ LARG a3, -FRAME_LEN+8*FLTS+3*PTRS(fp)
117
+ LARG a4, -FRAME_LEN+8*FLTS+4*PTRS(fp)
118
+ LARG a5, -FRAME_LEN+8*FLTS+5*PTRS(fp)
119
+ LARG a6, -FRAME_LEN+8*FLTS+6*PTRS(fp)
120
+ LARG a7, -FRAME_LEN+8*FLTS+7*PTRS(fp)
121
+
122
+ /* Call */
123
+ jalr t1
124
+
125
+ /* Save return values - only a0/a1 (fa0/fa1) are used */
126
+ #if FLTS
127
+ FSARG fa0, -FRAME_LEN+0*FLTS(fp)
128
+ FSARG fa1, -FRAME_LEN+1*FLTS(fp)
129
+ #endif
130
+
131
+ SARG a0, -FRAME_LEN+8*FLTS+0*PTRS(fp)
132
+ SARG a1, -FRAME_LEN+8*FLTS+1*PTRS(fp)
133
+
134
+ /* Restore and return */
135
+ addi sp, fp, -FRAME_LEN
136
+ .cfi_def_cfa 2, FRAME_LEN
137
+ LARG ra, -1*PTRS(fp)
138
+ .cfi_restore 1
139
+ LARG fp, -2*PTRS(fp)
140
+ .cfi_restore 8
141
+ ret
142
+ .cfi_endproc
143
+ .size ffi_call_asm, .-ffi_call_asm
144
+
145
+
146
+ /*
147
+ ffi_closure_asm. Expects address of the passed-in ffi_closure in t1.
148
+ void ffi_closure_inner(size_t *stackargs, struct call_context *regargs,
149
+ ffi_closure *closure);
150
+ */
151
+
152
+ .globl ffi_closure_asm
153
+ .hidden ffi_closure_asm
154
+ .type ffi_closure_asm, @function
155
+ ffi_closure_asm:
156
+ .cfi_startproc
157
+
158
+ addi sp, sp, -FRAME_LEN
159
+ .cfi_def_cfa_offset FRAME_LEN
160
+
161
+ /* make a frame */
162
+ SARG fp, FRAME_LEN - 2*PTRS(sp)
163
+ .cfi_offset 8, -2*PTRS
164
+ SARG ra, FRAME_LEN - 1*PTRS(sp)
165
+ .cfi_offset 1, -1*PTRS
166
+ addi fp, sp, FRAME_LEN
167
+
168
+ /* save arguments */
169
+ #if FLTS
170
+ FSARG fa0, 0*FLTS(sp)
171
+ FSARG fa1, 1*FLTS(sp)
172
+ FSARG fa2, 2*FLTS(sp)
173
+ FSARG fa3, 3*FLTS(sp)
174
+ FSARG fa4, 4*FLTS(sp)
175
+ FSARG fa5, 5*FLTS(sp)
176
+ FSARG fa6, 6*FLTS(sp)
177
+ FSARG fa7, 7*FLTS(sp)
178
+ #endif
179
+
180
+ SARG a0, 8*FLTS+0*PTRS(sp)
181
+ SARG a1, 8*FLTS+1*PTRS(sp)
182
+ SARG a2, 8*FLTS+2*PTRS(sp)
183
+ SARG a3, 8*FLTS+3*PTRS(sp)
184
+ SARG a4, 8*FLTS+4*PTRS(sp)
185
+ SARG a5, 8*FLTS+5*PTRS(sp)
186
+ SARG a6, 8*FLTS+6*PTRS(sp)
187
+ SARG a7, 8*FLTS+7*PTRS(sp)
188
+
189
+ /* enter C */
190
+ addi a0, sp, FRAME_LEN
191
+ mv a1, sp
192
+ mv a2, t1
193
+
194
+ call ffi_closure_inner
195
+
196
+ /* return values */
197
+ #if FLTS
198
+ FLARG fa0, 0*FLTS(sp)
199
+ FLARG fa1, 1*FLTS(sp)
200
+ #endif
201
+
202
+ LARG a0, 8*FLTS+0*PTRS(sp)
203
+ LARG a1, 8*FLTS+1*PTRS(sp)
204
+
205
+ /* restore and return */
206
+ LARG ra, FRAME_LEN-1*PTRS(sp)
207
+ .cfi_restore 1
208
+ LARG fp, FRAME_LEN-2*PTRS(sp)
209
+ .cfi_restore 8
210
+ addi sp, sp, FRAME_LEN
211
+ .cfi_def_cfa_offset 0
212
+ ret
213
+ .cfi_endproc
214
+ .size ffi_closure_asm, .-ffi_closure_asm
@@ -38,6 +38,7 @@ struct struct_align_##name { \
38
38
  char c; \
39
39
  type x; \
40
40
  }; \
41
+ FFI_EXTERN \
41
42
  maybe_const ffi_type ffi_type_##name = { \
42
43
  sizeof(type), \
43
44
  offsetof(struct struct_align_##name, x), \
@@ -52,6 +53,7 @@ struct struct_align_complex_##name { \
52
53
  char c; \
53
54
  _Complex type x; \
54
55
  }; \
56
+ FFI_EXTERN \
55
57
  maybe_const ffi_type ffi_type_complex_##name = { \
56
58
  sizeof(_Complex type), \
57
59
  offsetof(struct struct_align_complex_##name, x), \
@@ -60,7 +62,7 @@ maybe_const ffi_type ffi_type_complex_##name = { \
60
62
  }
61
63
 
62
64
  /* Size and alignment are fake here. They must not be 0. */
63
- const ffi_type ffi_type_void = {
65
+ FFI_EXTERN const ffi_type ffi_type_void = {
64
66
  1, 1, FFI_TYPE_VOID, NULL
65
67
  };
66
68
 
@@ -345,6 +345,15 @@ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue,
345
345
  size_t za = FFI_ALIGN (z, FFI_SIZEOF_ARG);
346
346
  size_t align = FFI_SIZEOF_ARG;
347
347
 
348
+ /* Issue 434: For thiscall and fastcall, if the paramter passed
349
+ as 64-bit integer or struct, all following integer paramters
350
+ will be passed on stack. */
351
+ if ((cabi == FFI_THISCALL || cabi == FFI_FASTCALL)
352
+ && (t == FFI_TYPE_SINT64
353
+ || t == FFI_TYPE_UINT64
354
+ || t == FFI_TYPE_STRUCT))
355
+ narg_reg = 2;
356
+
348
357
  /* Alignment rules for arguments are quite complex. Vectors and
349
358
  structures with 16 byte alignment get it. Note that long double
350
359
  on Darwin does have 16 byte alignment, and does not get this
@@ -475,6 +484,15 @@ ffi_closure_inner (struct closure_frame *frame, char *stack)
475
484
  if (t == FFI_TYPE_STRUCT && ty->alignment >= 16)
476
485
  align = 16;
477
486
 
487
+ /* Issue 434: For thiscall and fastcall, if the paramter passed
488
+ as 64-bit integer or struct, all following integer paramters
489
+ will be passed on stack. */
490
+ if ((cabi == FFI_THISCALL || cabi == FFI_FASTCALL)
491
+ && (t == FFI_TYPE_SINT64
492
+ || t == FFI_TYPE_UINT64
493
+ || t == FFI_TYPE_STRUCT))
494
+ narg_reg = 2;
495
+
478
496
  if (dir < 0)
479
497
  {
480
498
  /* ??? These reverse argument ABIs are probably too old
@@ -1,6 +1,6 @@
1
1
  /* -----------------------------------------------------------------------
2
- ffi64.c - Copyright (c) 2013 The Written Word, Inc.
3
- Copyright (c) 2011 Anthony Green
2
+ ffi64.c - Copyright (c) 2011, 2018 Anthony Green
3
+ Copyright (c) 2013 The Written Word, Inc.
4
4
  Copyright (c) 2008, 2010 Red Hat, Inc.
5
5
  Copyright (c) 2002, 2007 Bo Thorsen <bo@suse.de>
6
6
 
@@ -404,7 +404,7 @@ ffi_prep_cif_machdep (ffi_cif *cif)
404
404
  ffi_type *rtype;
405
405
 
406
406
  #ifndef __ILP32__
407
- if (cif->abi == FFI_EFI64)
407
+ if (cif->abi == FFI_EFI64 || cif->abi == FFI_GNUW64)
408
408
  return ffi_prep_cif_machdep_efi64(cif);
409
409
  #endif
410
410
  if (cif->abi != FFI_UNIX64)
@@ -677,8 +677,11 @@ void
677
677
  ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
678
678
  {
679
679
  #ifndef __ILP32__
680
- if (cif->abi == FFI_EFI64)
681
- return ffi_call_efi64(cif, fn, rvalue, avalue);
680
+ if (cif->abi == FFI_EFI64 || cif->abi == FFI_GNUW64)
681
+ {
682
+ ffi_call_efi64(cif, fn, rvalue, avalue);
683
+ return;
684
+ }
682
685
  #endif
683
686
  ffi_call_int (cif, fn, rvalue, avalue, NULL);
684
687
  }
@@ -694,8 +697,11 @@ ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue,
694
697
  void **avalue, void *closure)
695
698
  {
696
699
  #ifndef __ILP32__
697
- if (cif->abi == FFI_EFI64)
698
- ffi_call_go_efi64(cif, fn, rvalue, avalue, closure);
700
+ if (cif->abi == FFI_EFI64 || cif->abi == FFI_GNUW64)
701
+ {
702
+ ffi_call_go_efi64(cif, fn, rvalue, avalue, closure);
703
+ return;
704
+ }
699
705
  #endif
700
706
  ffi_call_int (cif, fn, rvalue, avalue, closure);
701
707
  }
@@ -732,7 +738,7 @@ ffi_prep_closure_loc (ffi_closure* closure,
732
738
  char *tramp = closure->tramp;
733
739
 
734
740
  #ifndef __ILP32__
735
- if (cif->abi == FFI_EFI64)
741
+ if (cif->abi == FFI_EFI64 || cif->abi == FFI_GNUW64)
736
742
  return ffi_prep_closure_loc_efi64(closure, cif, fun, user_data, codeloc);
737
743
  #endif
738
744
  if (cif->abi != FFI_UNIX64)
@@ -860,7 +866,7 @@ ffi_prep_go_closure (ffi_go_closure* closure, ffi_cif* cif,
860
866
  void (*fun)(ffi_cif*, void*, void**, void*))
861
867
  {
862
868
  #ifndef __ILP32__
863
- if (cif->abi == FFI_EFI64)
869
+ if (cif->abi == FFI_EFI64 || cif->abi == FFI_GNUW64)
864
870
  return ffi_prep_go_closure_efi64(closure, cif, fun);
865
871
  #endif
866
872
  if (cif->abi != FFI_UNIX64)
@@ -1,5 +1,5 @@
1
1
  /* -----------------------------------------------------------------*-C-*-
2
- ffitarget.h - Copyright (c) 2012, 2014 Anthony Green
2
+ ffitarget.h - Copyright (c) 2012, 2014, 2018 Anthony Green
3
3
  Copyright (c) 1996-2003, 2010 Red Hat, Inc.
4
4
  Copyright (C) 2008 Free Software Foundation, Inc.
5
5
 
@@ -80,15 +80,21 @@ typedef signed long ffi_sarg;
80
80
  typedef enum ffi_abi {
81
81
  #if defined(X86_WIN64)
82
82
  FFI_FIRST_ABI = 0,
83
- FFI_WIN64,
83
+ FFI_WIN64, /* sizeof(long double) == 8 - microsoft compilers */
84
+ FFI_GNUW64, /* sizeof(long double) == 16 - GNU compilers */
84
85
  FFI_LAST_ABI,
86
+ #ifdef __GNUC__
87
+ FFI_DEFAULT_ABI = FFI_GNUW64
88
+ #else
85
89
  FFI_DEFAULT_ABI = FFI_WIN64
90
+ #endif
86
91
 
87
92
  #elif defined(X86_64) || (defined (__x86_64__) && defined (X86_DARWIN))
88
93
  FFI_FIRST_ABI = 1,
89
94
  FFI_UNIX64,
90
95
  FFI_WIN64,
91
96
  FFI_EFI64 = FFI_WIN64,
97
+ FFI_GNUW64,
92
98
  FFI_LAST_ABI,
93
99
  FFI_DEFAULT_ABI = FFI_UNIX64
94
100
 
@@ -1,5 +1,6 @@
1
1
  /* -----------------------------------------------------------------------
2
- ffiw64.c - Copyright (c) 2014 Red Hat, Inc.
2
+ ffiw64.c - Copyright (c) 2018 Anthony Green
3
+ Copyright (c) 2014 Red Hat, Inc.
3
4
 
4
5
  x86 win64 Foreign Function Interface
5
6
 
@@ -52,8 +53,14 @@ EFI64(ffi_prep_cif_machdep)(ffi_cif *cif)
52
53
  {
53
54
  int flags, n;
54
55
 
55
- if (cif->abi != FFI_WIN64)
56
- return FFI_BAD_ABI;
56
+ switch (cif->abi)
57
+ {
58
+ case FFI_WIN64:
59
+ case FFI_GNUW64:
60
+ break;
61
+ default:
62
+ return FFI_BAD_ABI;
63
+ }
57
64
 
58
65
  flags = cif->rtype->type;
59
66
  switch (flags)
@@ -61,7 +68,9 @@ EFI64(ffi_prep_cif_machdep)(ffi_cif *cif)
61
68
  default:
62
69
  break;
63
70
  case FFI_TYPE_LONGDOUBLE:
64
- flags = FFI_TYPE_STRUCT;
71
+ /* GCC returns long double values by reference, like a struct */
72
+ if (cif->abi == FFI_GNUW64)
73
+ flags = FFI_TYPE_STRUCT;
65
74
  break;
66
75
  case FFI_TYPE_COMPLEX:
67
76
  flags = FFI_TYPE_STRUCT;
@@ -106,7 +115,7 @@ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue,
106
115
  size_t rsize;
107
116
  struct win64_call_frame *frame;
108
117
 
109
- FFI_ASSERT(cif->abi == FFI_WIN64);
118
+ FFI_ASSERT(cif->abi == FFI_GNUW64 || cif->abi == FFI_WIN64);
110
119
 
111
120
  flags = cif->flags;
112
121
  rsize = 0;
@@ -196,8 +205,14 @@ EFI64(ffi_prep_closure_loc)(ffi_closure* closure,
196
205
  };
197
206
  char *tramp = closure->tramp;
198
207
 
199
- if (cif->abi != FFI_WIN64)
200
- return FFI_BAD_ABI;
208
+ switch (cif->abi)
209
+ {
210
+ case FFI_WIN64:
211
+ case FFI_GNUW64:
212
+ break;
213
+ default:
214
+ return FFI_BAD_ABI;
215
+ }
201
216
 
202
217
  memcpy (tramp, trampoline, sizeof(trampoline));
203
218
  *(UINT64 *)(tramp + 16) = (uintptr_t)ffi_closure_win64;
@@ -213,8 +228,14 @@ ffi_status
213
228
  EFI64(ffi_prep_go_closure)(ffi_go_closure* closure, ffi_cif* cif,
214
229
  void (*fun)(ffi_cif*, void*, void**, void*))
215
230
  {
216
- if (cif->abi != FFI_WIN64)
217
- return FFI_BAD_ABI;
231
+ switch (cif->abi)
232
+ {
233
+ case FFI_WIN64:
234
+ case FFI_GNUW64:
235
+ break;
236
+ default:
237
+ return FFI_BAD_ABI;
238
+ }
218
239
 
219
240
  closure->tramp = ffi_go_closure_win64;
220
241
  closure->cif = cif;