ffi 1.9.23 → 1.9.24
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +66 -0
- data/Rakefile +1 -1
- data/ext/ffi_c/Call.c +5 -2
- data/ext/ffi_c/Function.c +8 -5
- data/ext/ffi_c/Thread.c +1 -0
- data/ext/ffi_c/extconf.rb +1 -0
- data/ext/ffi_c/libffi/.appveyor.yml +6 -4
- data/ext/ffi_c/libffi/.github/issue_template.md +10 -0
- data/ext/ffi_c/libffi/.gitignore +2 -0
- data/ext/ffi_c/libffi/.travis.yml +20 -16
- data/ext/ffi_c/libffi/.travis/ar-lib +270 -0
- data/ext/ffi_c/libffi/.travis/build.sh +34 -0
- data/ext/ffi_c/libffi/.travis/compile +351 -0
- data/ext/ffi_c/libffi/.travis/install.sh +11 -3
- data/ext/ffi_c/libffi/.travis/moxie-sim.exp +60 -0
- data/ext/ffi_c/libffi/.travis/site.exp +18 -0
- data/ext/ffi_c/libffi/LICENSE-BUILDTOOLS +352 -0
- data/ext/ffi_c/libffi/Makefile.am +4 -45
- data/ext/ffi_c/libffi/{README → README.md} +237 -230
- data/ext/ffi_c/libffi/configure.ac +10 -8
- data/ext/ffi_c/libffi/configure.host +5 -0
- data/ext/ffi_c/libffi/include/ffi.h.in +48 -26
- data/ext/ffi_c/libffi/include/ffi_common.h +2 -0
- data/ext/ffi_c/libffi/m4/ax_append_flag.m4 +18 -16
- data/ext/ffi_c/libffi/m4/ax_cc_maxopt.m4 +21 -8
- data/ext/ffi_c/libffi/m4/ax_cflags_warn_all.m4 +4 -4
- data/ext/ffi_c/libffi/m4/ax_check_compile_flag.m4 +9 -7
- data/ext/ffi_c/libffi/m4/ax_compiler_vendor.m4 +8 -5
- data/ext/ffi_c/libffi/m4/ax_configure_args.m4 +5 -5
- data/ext/ffi_c/libffi/m4/ax_enable_builddir.m4 +7 -6
- data/ext/ffi_c/libffi/m4/ax_gcc_archflag.m4 +99 -61
- data/ext/ffi_c/libffi/m4/ax_gcc_x86_cpuid.m4 +18 -8
- data/ext/ffi_c/libffi/m4/ax_require_defined.m4 +37 -0
- data/ext/ffi_c/libffi/msvcc.sh +82 -14
- data/ext/ffi_c/libffi/src/aarch64/ffi.c +8 -31
- data/ext/ffi_c/libffi/src/closures.c +31 -1
- data/ext/ffi_c/libffi/src/ia64/ffi.c +24 -6
- data/ext/ffi_c/libffi/src/ia64/ffitarget.h +2 -1
- data/ext/ffi_c/libffi/src/ia64/unix.S +6 -1
- data/ext/ffi_c/libffi/src/mips/ffi.c +29 -12
- data/ext/ffi_c/libffi/src/mips/ffitarget.h +7 -12
- data/ext/ffi_c/libffi/src/moxie/eabi.S +1 -1
- data/ext/ffi_c/libffi/src/moxie/ffi.c +18 -5
- data/ext/ffi_c/libffi/src/powerpc/ffi_linux64.c +45 -16
- data/ext/ffi_c/libffi/src/riscv/ffi.c +445 -0
- data/ext/ffi_c/libffi/src/riscv/ffitarget.h +68 -0
- data/ext/ffi_c/libffi/src/riscv/sysv.S +214 -0
- data/ext/ffi_c/libffi/src/types.c +3 -1
- data/ext/ffi_c/libffi/src/x86/ffi.c +18 -0
- data/ext/ffi_c/libffi/src/x86/ffi64.c +15 -9
- data/ext/ffi_c/libffi/src/x86/ffitarget.h +8 -2
- data/ext/ffi_c/libffi/src/x86/ffiw64.c +30 -9
- data/ext/ffi_c/libffi/src/xtensa/sysv.S +6 -1
- data/ext/ffi_c/libffi/testsuite/Makefile.am +108 -77
- data/ext/ffi_c/libffi/testsuite/lib/libffi.exp +195 -5
- data/ext/ffi_c/libffi/testsuite/libffi.bhaible/Makefile +28 -0
- data/ext/ffi_c/libffi/testsuite/libffi.bhaible/README +78 -0
- data/ext/ffi_c/libffi/testsuite/libffi.bhaible/alignof.h +50 -0
- data/ext/ffi_c/libffi/testsuite/libffi.bhaible/bhaible.exp +58 -0
- data/ext/ffi_c/libffi/testsuite/libffi.bhaible/test-call.c +1745 -0
- data/ext/ffi_c/libffi/testsuite/libffi.bhaible/test-callback.c +2885 -0
- data/ext/ffi_c/libffi/testsuite/libffi.bhaible/testcases.c +743 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/align_stdcall.c +46 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/call.exp +14 -1
- data/ext/ffi_c/libffi/testsuite/libffi.call/ffitest.h +3 -1
- data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct10.c +1 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct10.c +57 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/unwindtest.cc +1 -1
- data/ext/ffi_c/libffi/testsuite/libffi.call/unwindtest_ffi_call.cc +1 -1
- data/lib/ffi/library.rb +2 -4
- data/lib/ffi/platform/mips64-linux/types.conf +104 -0
- data/lib/ffi/platform/mipsisa32r6-linux/types.conf +102 -0
- data/lib/ffi/platform/mipsisa32r6el-linux/types.conf +102 -0
- data/lib/ffi/platform/mipsisa64r6-linux/types.conf +104 -0
- data/lib/ffi/platform/mipsisa64r6el-linux/types.conf +104 -0
- data/lib/ffi/version.rb +1 -1
- metadata +29 -3
data/ext/ffi_c/libffi/msvcc.sh
CHANGED
@@ -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
|
-
|
151
|
-
|
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
|
-
|
156
|
-
|
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
|
-
|
217
|
-
|
218
|
-
#
|
219
|
-
if
|
220
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
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
|
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
|
667
|
+
bytes, then the argument has been copied to memory, and
|
688
668
|
the argument is replaced by a pointer to the copy. */
|
689
|
-
|
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
|
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 (
|
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
|
-
|
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
|
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
|
-
|
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 *)(
|
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) && ((
|
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
|
}
|