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
@@ -44,17 +44,25 @@
44
44
 
45
45
  args_orig=$@
46
46
  args="-nologo -W3"
47
+ linkargs=
47
48
  static_crt=
48
49
  debug_crt=
49
50
  cl="cl"
50
51
  ml="ml"
51
52
  safeseh="-safeseh"
52
53
  output=
54
+ libpaths=
55
+ libversion=7
56
+ verbose=
53
57
 
54
58
  while [ $# -gt 0 ]
55
59
  do
56
60
  case $1
57
61
  in
62
+ --verbose)
63
+ $verbose=1
64
+ shift 1
65
+ ;;
58
66
  --version)
59
67
  args="-help"
60
68
  shift 1
@@ -147,13 +155,44 @@ do
147
155
  shift 1
148
156
  ;;
149
157
  -I)
150
- args="$args -I$2"
151
- includes="$includes -I$2"
158
+ p=$(cygpath -m $2)
159
+ args="$args -I$p"
160
+ includes="$includes -I$p"
152
161
  shift 2
153
162
  ;;
154
163
  -I*)
155
- args="$args $1"
156
- includes="$includes $1"
164
+ p=$(cygpath -m ${1#-I})
165
+ args="$args -I$p"
166
+ includes="$includes -I$p"
167
+ shift 1
168
+ ;;
169
+ -L)
170
+ p=$(cygpath -m $2)
171
+ linkargs="$linkargs -LIBPATH:$p"
172
+ shift 2
173
+ ;;
174
+ -L*)
175
+ p=$(cygpath -m ${1#-L})
176
+ linkargs="$linkargs -LIBPATH:$p"
177
+ shift 1
178
+ ;;
179
+ -link)
180
+ # add next argument verbatim to linker args
181
+ linkargs="$linkargs $2"
182
+ shift 2
183
+ ;;
184
+ -l*)
185
+ case $1
186
+ in
187
+ -lffi)
188
+ linkargs="$linkargs lib${1#-l}-${libversion}.lib"
189
+ ;;
190
+ *)
191
+ # ignore other libraries like -lm, hope they are
192
+ # covered by MSVCRT
193
+ # linkargs="$linkargs ${1#-l}.lib"
194
+ ;;
195
+ esac
157
196
  shift 1
158
197
  ;;
159
198
  -W|-Wextra)
@@ -169,6 +208,15 @@ do
169
208
  # libffi tests -pedantic with -Wall, so drop it also.
170
209
  shift 1
171
210
  ;;
211
+ -warn)
212
+ # ignore -warn all from libtool as well.
213
+ if test "$2" = "all"; then
214
+ shift 2
215
+ else
216
+ args="$args -warn"
217
+ shift 1
218
+ fi
219
+ ;;
172
220
  -Werror)
173
221
  args="$args -WX"
174
222
  shift 1
@@ -213,11 +261,16 @@ do
213
261
  esac
214
262
  done
215
263
 
216
- # If -Zi is specified, certain optimizations are implicitly disabled
217
- # by MSVC. Add back those optimizations if this is an optimized build.
218
- # NOTE: These arguments must come after all others.
219
- if [ -n "$opt" ]; then
220
- args="$args -link -OPT:REF -OPT:ICF -INCREMENTAL:NO"
264
+ if [ -n "$linkargs" ]; then
265
+
266
+ # If -Zi is specified, certain optimizations are implicitly disabled
267
+ # by MSVC. Add back those optimizations if this is an optimized build.
268
+ # NOTE: These arguments must come after all others.
269
+ if [ -n "$opt" ]; then
270
+ linkargs="$linkargs -OPT:REF -OPT:ICF -INCREMENTAL:NO"
271
+ fi
272
+
273
+ args="$args -link $linkargs"
221
274
  fi
222
275
 
223
276
  if [ -n "$static_crt" ]; then
@@ -235,12 +288,19 @@ if [ -n "$assembly" ]; then
235
288
  outdir="."
236
289
  fi
237
290
  ppsrc="$outdir/$(basename $src|sed 's/.S$/.asm/g')"
238
- echo "$cl -nologo -EP $includes $defines $src > $ppsrc"
291
+
292
+ if test -n "$verbose"; then
293
+ echo "$cl -nologo -EP $includes $defines $src > $ppsrc"
294
+ fi
295
+
239
296
  "$cl" -nologo -EP $includes $defines $src > $ppsrc || exit $?
240
297
  output="$(echo $output | sed 's%/F[dpa][^ ]*%%g')"
241
298
  args="-nologo $safeseh $single $output $ppsrc"
242
299
 
243
- echo "$ml $args"
300
+ if test -n "$verbose"; then
301
+ echo "$ml $args"
302
+ fi
303
+
244
304
  eval "\"$ml\" $args"
245
305
  result=$?
246
306
 
@@ -248,13 +308,21 @@ if [ -n "$assembly" ]; then
248
308
  #mv *.obj $outdir
249
309
  else
250
310
  args="$md $args"
251
- echo "$cl $args"
311
+
312
+ if test -n "$verbose"; then
313
+ echo "$cl $args"
314
+ fi
252
315
  # Return an error code of 1 if an invalid command line parameter is passed
253
- # instead of just ignoring it.
316
+ # instead of just ignoring it. Any output that is not a warning or an
317
+ # error is filtered so this command behaves more like gcc. cl.exe prints
318
+ # the name of the compiled file otherwise, which breaks the dejagnu checks
319
+ # for excess warnings and errors.
254
320
  eval "(\"$cl\" $args 2>&1 1>&3 | \
255
- awk '{print \$0} /D9002/ {error=1} END{exit error}' >&2) 3>&1"
321
+ awk '{print \$0} /D9002/ {error=1} END{exit error}' >&2) 3>&1 | \
322
+ awk '/warning|error/'"
256
323
  result=$?
257
324
  fi
258
325
 
259
326
  exit $result
260
327
 
328
+ # vim: noai:ts=4:sw=4
@@ -238,18 +238,13 @@ is_vfp_type (const ffi_type *ty)
238
238
  state.
239
239
 
240
240
  The terse state variable names match the names used in the AARCH64
241
- PCS.
242
-
243
- The struct area is allocated downwards from the top of the argument
244
- area. It is used to hold copies of structures passed by value that are
245
- bigger than 16 bytes. */
241
+ PCS. */
246
242
 
247
243
  struct arg_state
248
244
  {
249
245
  unsigned ngrn; /* Next general-purpose register number. */
250
246
  unsigned nsrn; /* Next vector register number. */
251
247
  size_t nsaa; /* Next stack offset. */
252
- size_t next_struct_area; /* Place to allocate big structs. */
253
248
 
254
249
  #if defined (__APPLE__)
255
250
  unsigned allocating_variadic;
@@ -258,12 +253,11 @@ struct arg_state
258
253
 
259
254
  /* Initialize a procedure call argument marshalling state. */
260
255
  static void
261
- arg_init (struct arg_state *state, size_t size)
256
+ arg_init (struct arg_state *state)
262
257
  {
263
258
  state->ngrn = 0;
264
259
  state->nsrn = 0;
265
260
  state->nsaa = 0;
266
- state->next_struct_area = size;
267
261
  #if defined (__APPLE__)
268
262
  state->allocating_variadic = 0;
269
263
  #endif
@@ -292,21 +286,6 @@ allocate_to_stack (struct arg_state *state, void *stack,
292
286
  return (char *)stack + nsaa;
293
287
  }
294
288
 
295
- /* Allocate and copy a structure that is passed by value on the stack and
296
- return a pointer to it. */
297
- static void *
298
- allocate_and_copy_struct_to_stack (struct arg_state *state, void *stack,
299
- size_t alignment, size_t size, void *value)
300
- {
301
- size_t dest = state->next_struct_area - size;
302
-
303
- /* Round down to the natural alignment of the value. */
304
- dest = ALIGN_DOWN (dest, alignment);
305
- state->next_struct_area = dest;
306
-
307
- return memcpy ((char *) stack + dest, value, size);
308
- }
309
-
310
289
  static ffi_arg
311
290
  extend_integer_type (void *source, int type)
312
291
  {
@@ -612,14 +591,13 @@ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *orig_rvalue,
612
591
  frame = stack + stack_bytes;
613
592
  rvalue = (rsize ? frame + 32 : orig_rvalue);
614
593
 
615
- arg_init (&state, stack_bytes);
594
+ arg_init (&state);
616
595
  for (i = 0, nargs = cif->nargs; i < nargs; i++)
617
596
  {
618
597
  ffi_type *ty = cif->arg_types[i];
619
598
  size_t s = ty->size;
620
599
  void *a = avalue[i];
621
600
  int h, t;
622
- void *dest;
623
601
 
624
602
  t = ty->type;
625
603
  switch (t)
@@ -667,6 +645,8 @@ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *orig_rvalue,
667
645
  case FFI_TYPE_STRUCT:
668
646
  case FFI_TYPE_COMPLEX:
669
647
  {
648
+ void *dest;
649
+
670
650
  h = is_vfp_type (ty);
671
651
  if (h)
672
652
  {
@@ -684,12 +664,9 @@ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *orig_rvalue,
684
664
  else if (s > 16)
685
665
  {
686
666
  /* If the argument is a composite type that is larger than 16
687
- bytes, then the argument is copied to memory, and
667
+ bytes, then the argument has been copied to memory, and
688
668
  the argument is replaced by a pointer to the copy. */
689
- dest = allocate_and_copy_struct_to_stack (&state, stack,
690
- ty->alignment, s,
691
- avalue[i]);
692
- a = &dest;
669
+ a = &avalue[i];
693
670
  t = FFI_TYPE_POINTER;
694
671
  s = sizeof (void *);
695
672
  goto do_pointer;
@@ -858,7 +835,7 @@ ffi_closure_SYSV_inner (ffi_cif *cif,
858
835
  int i, h, nargs, flags;
859
836
  struct arg_state state;
860
837
 
861
- arg_init (&state, cif->bytes);
838
+ arg_init (&state);
862
839
 
863
840
  for (i = 0, nargs = cif->nargs; i < nargs; i++)
864
841
  {
@@ -723,6 +723,36 @@ open_temp_exec_file (void)
723
723
  return fd;
724
724
  }
725
725
 
726
+ /* We need to allocate space in a file that will be backing a writable
727
+ mapping. Several problems exist with the usual approaches:
728
+ - fallocate() is Linux-only
729
+ - posix_fallocate() is not available on all platforms
730
+ - ftruncate() does not allocate space on filesystems with sparse files
731
+ Failure to allocate the space will cause SIGBUS to be thrown when
732
+ the mapping is subsequently written to. */
733
+ static int
734
+ allocate_space (int fd, off_t offset, off_t len)
735
+ {
736
+ static size_t page_size;
737
+
738
+ /* Obtain system page size. */
739
+ if (!page_size)
740
+ page_size = sysconf(_SC_PAGESIZE);
741
+
742
+ unsigned char buf[page_size];
743
+ memset (buf, 0, page_size);
744
+
745
+ while (len > 0)
746
+ {
747
+ off_t to_write = (len < page_size) ? len : page_size;
748
+ if (write (fd, buf, to_write) < to_write)
749
+ return -1;
750
+ len -= to_write;
751
+ }
752
+
753
+ return 0;
754
+ }
755
+
726
756
  /* Map in a chunk of memory from the temporary exec file into separate
727
757
  locations in the virtual memory address space, one writable and one
728
758
  executable. Returns the address of the writable portion, after
@@ -744,7 +774,7 @@ dlmmap_locked (void *start, size_t length, int prot, int flags, off_t offset)
744
774
 
745
775
  offset = execsize;
746
776
 
747
- if (ftruncate (execfd, offset + length))
777
+ if (allocate_space (execfd, offset, length))
748
778
  return MFAIL;
749
779
 
750
780
  flags &= ~(MAP_PRIVATE | MAP_ANONYMOUS);
@@ -220,8 +220,8 @@ hfa_element_type (ffi_type *type, int nested)
220
220
 
221
221
  /* Perform machine dependent cif processing. */
222
222
 
223
- ffi_status
224
- ffi_prep_cif_machdep(ffi_cif *cif)
223
+ static ffi_status
224
+ ffi_prep_cif_machdep_core(ffi_cif *cif)
225
225
  {
226
226
  int flags;
227
227
 
@@ -271,6 +271,22 @@ ffi_prep_cif_machdep(ffi_cif *cif)
271
271
  return FFI_OK;
272
272
  }
273
273
 
274
+ ffi_status
275
+ ffi_prep_cif_machdep(ffi_cif *cif)
276
+ {
277
+ cif->nfixedargs = cif->nargs;
278
+ return ffi_prep_cif_machdep_core(cif);
279
+ }
280
+
281
+ ffi_status
282
+ ffi_prep_cif_machdep_var(ffi_cif *cif,
283
+ unsigned int nfixedargs,
284
+ unsigned int ntotalargs MAYBE_UNUSED)
285
+ {
286
+ cif->nfixedargs = nfixedargs;
287
+ return ffi_prep_cif_machdep_core(cif);
288
+ }
289
+
274
290
  extern int ffi_call_unix (struct ia64_args *, PTR64, void (*)(void), UINT64);
275
291
 
276
292
  void
@@ -454,10 +470,11 @@ ffi_closure_unix_inner (ffi_closure *closure, struct ia64_args *stack,
454
470
  ffi_cif *cif;
455
471
  void **avalue;
456
472
  ffi_type **p_arg;
457
- long i, avn, gpcount, fpcount;
473
+ long i, avn, gpcount, fpcount, nfixedargs;
458
474
 
459
475
  cif = closure->cif;
460
476
  avn = cif->nargs;
477
+ nfixedargs = cif->nfixedargs;
461
478
  avalue = alloca (avn * sizeof (void *));
462
479
 
463
480
  /* If the structure return value is passed in memory get that location
@@ -468,6 +485,7 @@ ffi_closure_unix_inner (ffi_closure *closure, struct ia64_args *stack,
468
485
  gpcount = fpcount = 0;
469
486
  for (i = 0, p_arg = cif->arg_types; i < avn; i++, p_arg++)
470
487
  {
488
+ int named = i < nfixedargs;
471
489
  switch ((*p_arg)->type)
472
490
  {
473
491
  case FFI_TYPE_SINT8:
@@ -491,7 +509,7 @@ ffi_closure_unix_inner (ffi_closure *closure, struct ia64_args *stack,
491
509
  break;
492
510
 
493
511
  case FFI_TYPE_FLOAT:
494
- if (gpcount < 8 && fpcount < 8)
512
+ if (named && gpcount < 8 && fpcount < 8)
495
513
  {
496
514
  fpreg *addr = &stack->fp_regs[fpcount++];
497
515
  float result;
@@ -505,7 +523,7 @@ ffi_closure_unix_inner (ffi_closure *closure, struct ia64_args *stack,
505
523
  break;
506
524
 
507
525
  case FFI_TYPE_DOUBLE:
508
- if (gpcount < 8 && fpcount < 8)
526
+ if (named && gpcount < 8 && fpcount < 8)
509
527
  {
510
528
  fpreg *addr = &stack->fp_regs[fpcount++];
511
529
  double result;
@@ -521,7 +539,7 @@ ffi_closure_unix_inner (ffi_closure *closure, struct ia64_args *stack,
521
539
  case FFI_TYPE_LONGDOUBLE:
522
540
  if (gpcount & 1)
523
541
  gpcount++;
524
- if (LDBL_MANT_DIG == 64 && gpcount < 8 && fpcount < 8)
542
+ if (LDBL_MANT_DIG == 64 && named && gpcount < 8 && fpcount < 8)
525
543
  {
526
544
  fpreg *addr = &stack->fp_regs[fpcount++];
527
545
  __float80 result;
@@ -50,6 +50,7 @@ typedef enum ffi_abi {
50
50
  #define FFI_TRAMPOLINE_SIZE 24 /* Really the following struct, which */
51
51
  /* can be interpreted as a C function */
52
52
  /* descriptor: */
53
+ #define FFI_TARGET_SPECIFIC_VARIADIC 1
54
+ #define FFI_EXTRA_CIF_FIELDS unsigned nfixedargs
53
55
 
54
56
  #endif
55
-
@@ -175,7 +175,6 @@ ffi_call_unix:
175
175
  ;;
176
176
 
177
177
  .Lst_small_struct:
178
- add sp = -16, sp
179
178
  cmp.lt p6, p0 = 8, in3
180
179
  cmp.lt p7, p0 = 16, in3
181
180
  cmp.lt p8, p0 = 24, in3
@@ -191,6 +190,12 @@ ffi_call_unix:
191
190
  (p8) st8 [r18] = r11
192
191
  mov out1 = sp
193
192
  mov out2 = in3
193
+ ;;
194
+ // ia64 software calling convention requires
195
+ // top 16 bytes of stack to be scratch space
196
+ // PLT resolver uses that scratch space at
197
+ // 'memcpy' symbol reolution time
198
+ add sp = -16, sp
194
199
  br.call.sptk.many b0 = memcpy#
195
200
  ;;
196
201
  mov ar.pfs = loc0
@@ -29,6 +29,7 @@
29
29
  #include <ffi.h>
30
30
  #include <ffi_common.h>
31
31
 
32
+ #include <stdint.h>
32
33
  #include <stdlib.h>
33
34
 
34
35
  #ifdef __GNUC__
@@ -322,9 +323,10 @@ calc_n32_return_struct_flags(int soft_float, ffi_type *arg)
322
323
  #endif
323
324
 
324
325
  /* Perform machine dependent cif processing */
325
- ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
326
+ static ffi_status ffi_prep_cif_machdep_int(ffi_cif *cif, unsigned nfixedargs)
326
327
  {
327
328
  cif->flags = 0;
329
+ cif->mips_nfixedargs = nfixedargs;
328
330
 
329
331
  #ifdef FFI_MIPS_O32
330
332
  /* Set the flags necessary for O32 processing. FFI_O32_SOFT_FLOAT
@@ -333,7 +335,7 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
333
335
 
334
336
  if (cif->rtype->type != FFI_TYPE_STRUCT && cif->abi == FFI_O32)
335
337
  {
336
- if (cif->nargs > 0)
338
+ if (cif->nargs > 0 && cif->nargs == nfixedargs)
337
339
  {
338
340
  switch ((cif->arg_types)[0]->type)
339
341
  {
@@ -450,7 +452,9 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
450
452
  while (count-- > 0 && arg_reg < 8)
451
453
  {
452
454
  type = (cif->arg_types)[index]->type;
453
- if (soft_float)
455
+
456
+ // Pass variadic arguments in integer registers even if they're floats
457
+ if (soft_float || index >= nfixedargs)
454
458
  {
455
459
  switch (type)
456
460
  {
@@ -476,7 +480,7 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
476
480
  /* Align it. */
477
481
  arg_reg = FFI_ALIGN(arg_reg, 2);
478
482
  /* Treat it as two adjacent doubles. */
479
- if (soft_float)
483
+ if (soft_float || index >= nfixedargs)
480
484
  {
481
485
  arg_reg += 2;
482
486
  }
@@ -493,7 +497,7 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
493
497
 
494
498
  case FFI_TYPE_STRUCT:
495
499
  loc = arg_reg * FFI_SIZEOF_ARG;
496
- cif->flags += calc_n32_struct_flags(soft_float,
500
+ cif->flags += calc_n32_struct_flags(soft_float || index >= nfixedargs,
497
501
  (cif->arg_types)[index],
498
502
  &loc, &arg_reg);
499
503
  break;
@@ -578,6 +582,18 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
578
582
  return FFI_OK;
579
583
  }
580
584
 
585
+ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
586
+ {
587
+ return ffi_prep_cif_machdep_int(cif, cif->nargs);
588
+ }
589
+
590
+ ffi_status ffi_prep_cif_machdep_var(ffi_cif *cif,
591
+ unsigned nfixedargs,
592
+ unsigned ntotalargs MAYBE_UNUSED)
593
+ {
594
+ return ffi_prep_cif_machdep_int(cif, nfixedargs);
595
+ }
596
+
581
597
  /* Low level routine for calling O32 functions */
582
598
  extern int ffi_call_O32(void (*)(char *, extended_cif *, int, int),
583
599
  extended_cif *, unsigned,
@@ -801,13 +817,14 @@ ffi_closure_mips_inner_O32 (ffi_cif *cif,
801
817
  avalue = alloca (cif->nargs * sizeof (ffi_arg));
802
818
  avaluep = alloca (cif->nargs * sizeof (ffi_arg));
803
819
 
804
- seen_int = (cif->abi == FFI_O32_SOFT_FLOAT);
820
+ seen_int = (cif->abi == FFI_O32_SOFT_FLOAT) || (cif->mips_nfixedargs != cif->nargs);
805
821
  argn = 0;
806
822
 
807
823
  if ((cif->flags >> (FFI_FLAG_BITS * 2)) == FFI_TYPE_STRUCT)
808
824
  {
809
- rvalue = (void *)(UINT32)ar[0];
825
+ rvalue = (void *)(uintptr_t)ar[0];
810
826
  argn = 1;
827
+ seen_int = 1;
811
828
  }
812
829
 
813
830
  i = 0;
@@ -816,6 +833,8 @@ ffi_closure_mips_inner_O32 (ffi_cif *cif,
816
833
 
817
834
  while (i < avn)
818
835
  {
836
+ if (arg_types[i]->alignment == 8 && (argn & 0x1))
837
+ argn++;
819
838
  if (i < 2 && !seen_int &&
820
839
  (arg_types[i]->type == FFI_TYPE_FLOAT ||
821
840
  arg_types[i]->type == FFI_TYPE_DOUBLE ||
@@ -830,8 +849,6 @@ ffi_closure_mips_inner_O32 (ffi_cif *cif,
830
849
  }
831
850
  else
832
851
  {
833
- if (arg_types[i]->alignment == 8 && (argn & 0x1))
834
- argn++;
835
852
  switch (arg_types[i]->type)
836
853
  {
837
854
  case FFI_TYPE_SINT8:
@@ -981,8 +998,8 @@ ffi_closure_mips_inner_N32 (ffi_cif *cif,
981
998
  || arg_types[i]->type == FFI_TYPE_DOUBLE
982
999
  || arg_types[i]->type == FFI_TYPE_LONGDOUBLE)
983
1000
  {
984
- argp = (argn >= 8 || soft_float) ? ar + argn : fpr + argn;
985
- if ((arg_types[i]->type == FFI_TYPE_LONGDOUBLE) && ((unsigned)argp & (arg_types[i]->alignment-1)))
1001
+ argp = (argn >= 8 || i >= cif->mips_nfixedargs || soft_float) ? ar + argn : fpr + argn;
1002
+ if ((arg_types[i]->type == FFI_TYPE_LONGDOUBLE) && ((uintptr_t)argp & (arg_types[i]->alignment-1)))
986
1003
  {
987
1004
  argp=(ffi_arg*)FFI_ALIGN(argp,arg_types[i]->alignment);
988
1005
  argn++;
@@ -1050,7 +1067,7 @@ ffi_closure_mips_inner_N32 (ffi_cif *cif,
1050
1067
  it was passed in registers. */
1051
1068
  avaluep[i] = alloca(arg_types[i]->size);
1052
1069
  copy_struct_N32(avaluep[i], 0, cif->abi, arg_types[i],
1053
- argn, 0, ar, fpr, soft_float);
1070
+ argn, 0, ar, fpr, i >= cif->mips_nfixedargs || soft_float);
1054
1071
 
1055
1072
  break;
1056
1073
  }