ffi 1.9.21 → 1.9.22
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of ffi might be problematic. Click here for more details.
- checksums.yaml +5 -5
- checksums.yaml.gz.sig +3 -0
- data.tar.gz.sig +0 -0
- data/.gitignore +22 -0
- data/.gitmodules +3 -0
- data/.travis.yml +52 -0
- data/.yardopts +5 -0
- data/Gemfile +15 -0
- data/{spec/ffi/LICENSE.SPECS → LICENSE.SPECS} +1 -1
- data/README.md +1 -1
- data/Rakefile +28 -3
- data/appveyor.yml +22 -0
- data/ext/ffi_c/Call.c +1 -22
- data/ext/ffi_c/Call.h +0 -9
- data/ext/ffi_c/Closure.c +54 -0
- data/ext/ffi_c/{ClosurePool.h → Closure.h} +13 -23
- data/ext/ffi_c/Function.c +16 -25
- data/ext/ffi_c/Function.h +1 -2
- data/ext/ffi_c/FunctionInfo.c +0 -4
- data/ext/ffi_c/MethodHandle.c +33 -268
- data/ext/ffi_c/extconf.rb +3 -3
- data/ext/ffi_c/ffi.c +2 -2
- data/ext/ffi_c/libffi.bsd.mk +3 -3
- data/ext/ffi_c/libffi.darwin.mk +1 -1
- data/ext/ffi_c/libffi.gnu.mk +1 -1
- data/ext/ffi_c/libffi.mk +2 -2
- data/ext/ffi_c/libffi.vc.mk +1 -1
- data/ext/ffi_c/libffi.vc64.mk +1 -1
- data/ext/ffi_c/libffi/.appveyor.yml +48 -0
- data/ext/ffi_c/libffi/.gitignore +36 -0
- data/ext/ffi_c/libffi/.travis.yml +30 -0
- data/ext/ffi_c/libffi/.travis/install.sh +14 -0
- data/ext/ffi_c/libffi/Makefile.am +5 -3
- data/ext/ffi_c/libffi/acinclude.m4 +6 -0
- data/ext/ffi_c/libffi/autogen.sh +1 -1
- data/ext/ffi_c/libffi/config.guess +1466 -0
- data/ext/ffi_c/libffi/config.sub +1836 -0
- data/ext/ffi_c/libffi/configure.ac +2 -2
- data/ext/ffi_c/libffi/configure.host +15 -3
- data/ext/ffi_c/libffi/generate-darwin-source-and-headers.py +11 -15
- data/ext/ffi_c/libffi/include/ffi.h.in +6 -1
- data/ext/ffi_c/libffi/libffi.xcodeproj/project.pbxproj +465 -59
- data/ext/ffi_c/libffi/src/aarch64/ffi.c +33 -10
- data/ext/ffi_c/libffi/src/aarch64/sysv.S +2 -2
- data/ext/ffi_c/libffi/src/arm/ffi.c +12 -1
- data/ext/ffi_c/libffi/src/arm/sysv.S +1 -1
- data/ext/ffi_c/libffi/src/closures.c +143 -97
- data/ext/ffi_c/libffi/src/ia64/unix.S +2 -0
- data/ext/ffi_c/libffi/src/mips/ffi.c +8 -0
- data/ext/ffi_c/libffi/src/mips/ffitarget.h +1 -1
- data/ext/ffi_c/libffi/src/mips/n32.S +2 -0
- data/ext/ffi_c/libffi/src/powerpc/aix.S +239 -1
- data/ext/ffi_c/libffi/src/powerpc/aix_closure.S +250 -3
- data/ext/ffi_c/libffi/src/powerpc/ffi_darwin.c +86 -5
- data/ext/ffi_c/libffi/src/powerpc/ffitarget.h +3 -0
- data/ext/ffi_c/libffi/src/x86/ffi.c +3 -1
- data/ext/ffi_c/libffi/src/x86/ffi64.c +26 -5
- data/ext/ffi_c/libffi/src/x86/sysv.S +2 -2
- data/ext/ffi_c/libffi/src/x86/unix64.S +1 -1
- data/ext/ffi_c/libffi/src/x86/win64.S +1 -1
- data/ext/ffi_c/libffi/testsuite/Makefile.am +2 -1
- data/ext/ffi_c/libffi/testsuite/lib/libffi.exp +2 -1
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3float.c +95 -0
- data/ffi.gemspec +14 -1
- data/lib/ffi/library.rb +1 -1
- data/lib/ffi/version.rb +1 -1
- data/samples/getlogin.rb +8 -0
- data/samples/getpid.rb +8 -0
- data/samples/gettimeofday.rb +18 -0
- data/samples/hello.rb +7 -0
- data/samples/inotify.rb +60 -0
- data/samples/pty.rb +76 -0
- data/samples/qsort.rb +21 -0
- data/samples/sample_helper.rb +6 -0
- metadata +59 -81
- metadata.gz.sig +0 -0
- data/ext/ffi_c/ClosurePool.c +0 -283
- data/gen/Rakefile +0 -30
- data/libtest/Benchmark.c +0 -52
- data/libtest/BoolTest.c +0 -34
- data/libtest/BufferTest.c +0 -31
- data/libtest/ClosureTest.c +0 -205
- data/libtest/EnumTest.c +0 -51
- data/libtest/FunctionTest.c +0 -70
- data/libtest/GNUmakefile +0 -149
- data/libtest/GlobalVariable.c +0 -62
- data/libtest/LastErrorTest.c +0 -21
- data/libtest/NumberTest.c +0 -132
- data/libtest/PointerTest.c +0 -63
- data/libtest/ReferenceTest.c +0 -23
- data/libtest/StringTest.c +0 -34
- data/libtest/StructTest.c +0 -243
- data/libtest/UnionTest.c +0 -43
- data/libtest/VariadicTest.c +0 -99
- data/spec/ffi/async_callback_spec.rb +0 -35
- data/spec/ffi/bitmask_spec.rb +0 -575
- data/spec/ffi/bool_spec.rb +0 -32
- data/spec/ffi/buffer_spec.rb +0 -279
- data/spec/ffi/callback_spec.rb +0 -773
- data/spec/ffi/custom_param_type.rb +0 -37
- data/spec/ffi/custom_type_spec.rb +0 -74
- data/spec/ffi/dup_spec.rb +0 -52
- data/spec/ffi/enum_spec.rb +0 -423
- data/spec/ffi/errno_spec.rb +0 -20
- data/spec/ffi/ffi_spec.rb +0 -28
- data/spec/ffi/fixtures/Benchmark.c +0 -52
- data/spec/ffi/fixtures/BitmaskTest.c +0 -51
- data/spec/ffi/fixtures/BoolTest.c +0 -34
- data/spec/ffi/fixtures/BufferTest.c +0 -31
- data/spec/ffi/fixtures/ClosureTest.c +0 -205
- data/spec/ffi/fixtures/EnumTest.c +0 -51
- data/spec/ffi/fixtures/FunctionTest.c +0 -142
- data/spec/ffi/fixtures/GNUmakefile +0 -149
- data/spec/ffi/fixtures/GlobalVariable.c +0 -62
- data/spec/ffi/fixtures/LastErrorTest.c +0 -21
- data/spec/ffi/fixtures/NumberTest.c +0 -132
- data/spec/ffi/fixtures/PipeHelper.h +0 -21
- data/spec/ffi/fixtures/PipeHelperPosix.c +0 -41
- data/spec/ffi/fixtures/PipeHelperWindows.c +0 -72
- data/spec/ffi/fixtures/PointerTest.c +0 -63
- data/spec/ffi/fixtures/ReferenceTest.c +0 -23
- data/spec/ffi/fixtures/StringTest.c +0 -34
- data/spec/ffi/fixtures/StructTest.c +0 -243
- data/spec/ffi/fixtures/UnionTest.c +0 -43
- data/spec/ffi/fixtures/VariadicTest.c +0 -99
- data/spec/ffi/fixtures/classes.rb +0 -438
- data/spec/ffi/function_spec.rb +0 -97
- data/spec/ffi/io_spec.rb +0 -16
- data/spec/ffi/library_spec.rb +0 -286
- data/spec/ffi/long_double.rb +0 -30
- data/spec/ffi/managed_struct_spec.rb +0 -68
- data/spec/ffi/memorypointer_spec.rb +0 -78
- data/spec/ffi/number_spec.rb +0 -247
- data/spec/ffi/platform_spec.rb +0 -114
- data/spec/ffi/pointer_spec.rb +0 -285
- data/spec/ffi/rbx/attach_function_spec.rb +0 -34
- data/spec/ffi/rbx/memory_pointer_spec.rb +0 -198
- data/spec/ffi/rbx/spec_helper.rb +0 -6
- data/spec/ffi/rbx/struct_spec.rb +0 -18
- data/spec/ffi/spec_helper.rb +0 -93
- data/spec/ffi/string_spec.rb +0 -118
- data/spec/ffi/strptr_spec.rb +0 -50
- data/spec/ffi/struct_by_ref_spec.rb +0 -43
- data/spec/ffi/struct_callback_spec.rb +0 -69
- data/spec/ffi/struct_initialize_spec.rb +0 -35
- data/spec/ffi/struct_packed_spec.rb +0 -50
- data/spec/ffi/struct_spec.rb +0 -882
- data/spec/ffi/typedef_spec.rb +0 -91
- data/spec/ffi/union_spec.rb +0 -67
- data/spec/ffi/variadic_spec.rb +0 -132
- data/spec/spec.opts +0 -4
@@ -231,20 +231,25 @@ is_vfp_type (const ffi_type *ty)
|
|
231
231
|
|
232
232
|
/* All tests succeeded. Encode the result. */
|
233
233
|
done:
|
234
|
-
return candidate * 4 + (4 - ele_count);
|
234
|
+
return candidate * 4 + (4 - (int)ele_count);
|
235
235
|
}
|
236
236
|
|
237
237
|
/* Representation of the procedure call argument marshalling
|
238
238
|
state.
|
239
239
|
|
240
240
|
The terse state variable names match the names used in the AARCH64
|
241
|
-
PCS.
|
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. */
|
242
246
|
|
243
247
|
struct arg_state
|
244
248
|
{
|
245
249
|
unsigned ngrn; /* Next general-purpose register number. */
|
246
250
|
unsigned nsrn; /* Next vector register number. */
|
247
251
|
size_t nsaa; /* Next stack offset. */
|
252
|
+
size_t next_struct_area; /* Place to allocate big structs. */
|
248
253
|
|
249
254
|
#if defined (__APPLE__)
|
250
255
|
unsigned allocating_variadic;
|
@@ -253,11 +258,12 @@ struct arg_state
|
|
253
258
|
|
254
259
|
/* Initialize a procedure call argument marshalling state. */
|
255
260
|
static void
|
256
|
-
arg_init (struct arg_state *state)
|
261
|
+
arg_init (struct arg_state *state, size_t size)
|
257
262
|
{
|
258
263
|
state->ngrn = 0;
|
259
264
|
state->nsrn = 0;
|
260
265
|
state->nsaa = 0;
|
266
|
+
state->next_struct_area = size;
|
261
267
|
#if defined (__APPLE__)
|
262
268
|
state->allocating_variadic = 0;
|
263
269
|
#endif
|
@@ -286,6 +292,21 @@ allocate_to_stack (struct arg_state *state, void *stack,
|
|
286
292
|
return (char *)stack + nsaa;
|
287
293
|
}
|
288
294
|
|
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
|
+
|
289
310
|
static ffi_arg
|
290
311
|
extend_integer_type (void *source, int type)
|
291
312
|
{
|
@@ -528,7 +549,7 @@ ffi_prep_cif_machdep (ffi_cif *cif)
|
|
528
549
|
}
|
529
550
|
|
530
551
|
/* Round the stack up to a multiple of the stack alignment requirement. */
|
531
|
-
cif->bytes = FFI_ALIGN(bytes, 16);
|
552
|
+
cif->bytes = (unsigned) FFI_ALIGN(bytes, 16);
|
532
553
|
cif->flags = flags;
|
533
554
|
#if defined (__APPLE__)
|
534
555
|
cif->aarch64_nfixedargs = 0;
|
@@ -591,13 +612,14 @@ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *orig_rvalue,
|
|
591
612
|
frame = stack + stack_bytes;
|
592
613
|
rvalue = (rsize ? frame + 32 : orig_rvalue);
|
593
614
|
|
594
|
-
arg_init (&state);
|
615
|
+
arg_init (&state, stack_bytes);
|
595
616
|
for (i = 0, nargs = cif->nargs; i < nargs; i++)
|
596
617
|
{
|
597
618
|
ffi_type *ty = cif->arg_types[i];
|
598
619
|
size_t s = ty->size;
|
599
620
|
void *a = avalue[i];
|
600
621
|
int h, t;
|
622
|
+
void *dest;
|
601
623
|
|
602
624
|
t = ty->type;
|
603
625
|
switch (t)
|
@@ -645,8 +667,6 @@ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *orig_rvalue,
|
|
645
667
|
case FFI_TYPE_STRUCT:
|
646
668
|
case FFI_TYPE_COMPLEX:
|
647
669
|
{
|
648
|
-
void *dest;
|
649
|
-
|
650
670
|
h = is_vfp_type (ty);
|
651
671
|
if (h)
|
652
672
|
{
|
@@ -664,9 +684,12 @@ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *orig_rvalue,
|
|
664
684
|
else if (s > 16)
|
665
685
|
{
|
666
686
|
/* If the argument is a composite type that is larger than 16
|
667
|
-
bytes, then the argument
|
687
|
+
bytes, then the argument is copied to memory, and
|
668
688
|
the argument is replaced by a pointer to the copy. */
|
669
|
-
|
689
|
+
dest = allocate_and_copy_struct_to_stack (&state, stack,
|
690
|
+
ty->alignment, s,
|
691
|
+
avalue[i]);
|
692
|
+
a = &dest;
|
670
693
|
t = FFI_TYPE_POINTER;
|
671
694
|
s = sizeof (void *);
|
672
695
|
goto do_pointer;
|
@@ -835,7 +858,7 @@ ffi_closure_SYSV_inner (ffi_cif *cif,
|
|
835
858
|
int i, h, nargs, flags;
|
836
859
|
struct arg_state state;
|
837
860
|
|
838
|
-
arg_init (&state);
|
861
|
+
arg_init (&state, cif->bytes);
|
839
862
|
|
840
863
|
for (i = 0, nargs = cif->nargs; i < nargs; i++)
|
841
864
|
{
|
@@ -296,7 +296,7 @@ CNAME(ffi_closure_SYSV):
|
|
296
296
|
nop
|
297
297
|
8: ldr s3, [x3, #12] /* S4 */
|
298
298
|
nop
|
299
|
-
9: ldr s2, [
|
299
|
+
9: ldr s2, [x3, #8] /* S3 */
|
300
300
|
nop
|
301
301
|
10: ldp s0, s1, [x3] /* S2 */
|
302
302
|
b 99f
|
@@ -358,7 +358,7 @@ CNAME(ffi_closure_SYSV):
|
|
358
358
|
#if FFI_EXEC_TRAMPOLINE_TABLE
|
359
359
|
|
360
360
|
#ifdef __MACH__
|
361
|
-
#include <mach/vm_param.h>
|
361
|
+
#include <mach/machine/vm_param.h>
|
362
362
|
.align PAGE_MAX_SHIFT
|
363
363
|
CNAME(ffi_closure_trampoline_table_page):
|
364
364
|
.rept PAGE_MAX_SIZE / FFI_TRAMPOLINE_SIZE
|
@@ -31,13 +31,14 @@
|
|
31
31
|
#include <fficonfig.h>
|
32
32
|
#include <ffi.h>
|
33
33
|
#include <ffi_common.h>
|
34
|
+
#include <stdint.h>
|
34
35
|
#include <stdlib.h>
|
35
36
|
#include "internal.h"
|
36
37
|
|
37
38
|
#if FFI_EXEC_TRAMPOLINE_TABLE
|
38
39
|
|
39
40
|
#ifdef __MACH__
|
40
|
-
#include <mach/vm_param.h>
|
41
|
+
#include <mach/machine/vm_param.h>
|
41
42
|
#endif
|
42
43
|
|
43
44
|
#else
|
@@ -419,6 +420,11 @@ ffi_prep_incoming_args_SYSV (ffi_cif *cif, void *rvalue,
|
|
419
420
|
rvalue = *(void **) argp;
|
420
421
|
argp += 4;
|
421
422
|
}
|
423
|
+
else
|
424
|
+
{
|
425
|
+
if (cif->rtype->size && cif->rtype->size < 4)
|
426
|
+
*(uint32_t *) rvalue = 0;
|
427
|
+
}
|
422
428
|
|
423
429
|
for (i = 0, n = cif->nargs; i < n; i++)
|
424
430
|
{
|
@@ -566,8 +572,13 @@ ffi_prep_closure_loc (ffi_closure * closure,
|
|
566
572
|
config[1] = closure_func;
|
567
573
|
#else
|
568
574
|
memcpy (closure->tramp, ffi_arm_trampoline, 8);
|
575
|
+
#if defined (__QNX__)
|
576
|
+
msync(closure->tramp, 8, 0x1000000); /* clear data map */
|
577
|
+
msync(codeloc, 8, 0x1000000); /* clear insn map */
|
578
|
+
#else
|
569
579
|
__clear_cache(closure->tramp, closure->tramp + 8); /* clear data map */
|
570
580
|
__clear_cache(codeloc, codeloc + 8); /* clear insn map */
|
581
|
+
#endif
|
571
582
|
*(void (**)(void))(closure->tramp + 8) = closure_func;
|
572
583
|
#endif
|
573
584
|
|
@@ -34,6 +34,82 @@
|
|
34
34
|
#include <ffi.h>
|
35
35
|
#include <ffi_common.h>
|
36
36
|
|
37
|
+
#ifdef __NetBSD__
|
38
|
+
#include <sys/param.h>
|
39
|
+
#endif
|
40
|
+
|
41
|
+
#if __NetBSD_Version__ - 0 >= 799007200
|
42
|
+
/* NetBSD with PROT_MPROTECT */
|
43
|
+
#include <sys/mman.h>
|
44
|
+
|
45
|
+
#include <stddef.h>
|
46
|
+
#include <unistd.h>
|
47
|
+
|
48
|
+
static const size_t overhead =
|
49
|
+
(sizeof(max_align_t) > sizeof(void *) + sizeof(size_t)) ?
|
50
|
+
sizeof(max_align_t)
|
51
|
+
: sizeof(void *) + sizeof(size_t);
|
52
|
+
|
53
|
+
#define ADD_TO_POINTER(p, d) ((void *)((uintptr_t)(p) + (d)))
|
54
|
+
|
55
|
+
void *
|
56
|
+
ffi_closure_alloc (size_t size, void **code)
|
57
|
+
{
|
58
|
+
static size_t page_size;
|
59
|
+
size_t rounded_size;
|
60
|
+
void *codeseg, *dataseg;
|
61
|
+
int prot;
|
62
|
+
|
63
|
+
/* Expect that PAX mprotect is active and a separate code mapping is necessary. */
|
64
|
+
if (!code)
|
65
|
+
return NULL;
|
66
|
+
|
67
|
+
/* Obtain system page size. */
|
68
|
+
if (!page_size)
|
69
|
+
page_size = sysconf(_SC_PAGESIZE);
|
70
|
+
|
71
|
+
/* Round allocation size up to the next page, keeping in mind the size field and pointer to code map. */
|
72
|
+
rounded_size = (size + overhead + page_size - 1) & ~(page_size - 1);
|
73
|
+
|
74
|
+
/* Primary mapping is RW, but request permission to switch to PROT_EXEC later. */
|
75
|
+
prot = PROT_READ | PROT_WRITE | PROT_MPROTECT(PROT_EXEC);
|
76
|
+
dataseg = mmap(NULL, rounded_size, prot, MAP_ANON | MAP_PRIVATE, -1, 0);
|
77
|
+
if (dataseg == MAP_FAILED)
|
78
|
+
return NULL;
|
79
|
+
|
80
|
+
/* Create secondary mapping and switch it to RX. */
|
81
|
+
codeseg = mremap(dataseg, rounded_size, NULL, rounded_size, MAP_REMAPDUP);
|
82
|
+
if (codeseg == MAP_FAILED) {
|
83
|
+
munmap(dataseg, rounded_size);
|
84
|
+
return NULL;
|
85
|
+
}
|
86
|
+
if (mprotect(codeseg, rounded_size, PROT_READ | PROT_EXEC) == -1) {
|
87
|
+
munmap(codeseg, rounded_size);
|
88
|
+
munmap(dataseg, rounded_size);
|
89
|
+
return NULL;
|
90
|
+
}
|
91
|
+
|
92
|
+
/* Remember allocation size and location of the secondary mapping for ffi_closure_free. */
|
93
|
+
memcpy(dataseg, &rounded_size, sizeof(rounded_size));
|
94
|
+
memcpy(ADD_TO_POINTER(dataseg, sizeof(size_t)), &codeseg, sizeof(void *));
|
95
|
+
*code = ADD_TO_POINTER(codeseg, overhead);
|
96
|
+
return ADD_TO_POINTER(dataseg, overhead);
|
97
|
+
}
|
98
|
+
|
99
|
+
void
|
100
|
+
ffi_closure_free (void *ptr)
|
101
|
+
{
|
102
|
+
void *codeseg, *dataseg;
|
103
|
+
size_t rounded_size;
|
104
|
+
|
105
|
+
dataseg = ADD_TO_POINTER(ptr, -overhead);
|
106
|
+
memcpy(&rounded_size, dataseg, sizeof(rounded_size));
|
107
|
+
memcpy(&codeseg, ADD_TO_POINTER(dataseg, sizeof(size_t)), sizeof(void *));
|
108
|
+
munmap(dataseg, rounded_size);
|
109
|
+
munmap(codeseg, rounded_size);
|
110
|
+
}
|
111
|
+
#else /* !NetBSD with PROT_MPROTECT */
|
112
|
+
|
37
113
|
#if !FFI_MMAP_EXEC_WRIT && !FFI_EXEC_TRAMPOLINE_TABLE
|
38
114
|
# if __linux__ && !defined(__ANDROID__)
|
39
115
|
/* This macro indicates it may be forbidden to map anonymous memory
|
@@ -55,7 +131,7 @@
|
|
55
131
|
#endif
|
56
132
|
|
57
133
|
#if FFI_MMAP_EXEC_WRIT && !defined FFI_MMAP_EXEC_SELINUX
|
58
|
-
#
|
134
|
+
# if defined(__linux__) && !defined(__ANDROID__)
|
59
135
|
/* When defined to 1 check for SELinux and if SELinux is active,
|
60
136
|
don't attempt PROT_EXEC|PROT_WRITE mapping at all, as that
|
61
137
|
might cause audit messages. */
|
@@ -107,91 +183,81 @@ static pthread_mutex_t ffi_trampoline_lock = PTHREAD_MUTEX_INITIALIZER;
|
|
107
183
|
static ffi_trampoline_table *ffi_trampoline_tables = NULL;
|
108
184
|
|
109
185
|
static ffi_trampoline_table *
|
110
|
-
ffi_trampoline_table_alloc ()
|
186
|
+
ffi_trampoline_table_alloc (void)
|
111
187
|
{
|
112
|
-
ffi_trampoline_table *table
|
188
|
+
ffi_trampoline_table *table;
|
189
|
+
vm_address_t config_page;
|
190
|
+
vm_address_t trampoline_page;
|
191
|
+
vm_address_t trampoline_page_template;
|
192
|
+
vm_prot_t cur_prot;
|
193
|
+
vm_prot_t max_prot;
|
194
|
+
kern_return_t kt;
|
195
|
+
uint16_t i;
|
196
|
+
|
197
|
+
/* Allocate two pages -- a config page and a placeholder page */
|
198
|
+
config_page = 0x0;
|
199
|
+
kt = vm_allocate (mach_task_self (), &config_page, PAGE_MAX_SIZE * 2,
|
200
|
+
VM_FLAGS_ANYWHERE);
|
201
|
+
if (kt != KERN_SUCCESS)
|
202
|
+
return NULL;
|
113
203
|
|
114
|
-
/*
|
115
|
-
|
204
|
+
/* Remap the trampoline table on top of the placeholder page */
|
205
|
+
trampoline_page = config_page + PAGE_MAX_SIZE;
|
206
|
+
trampoline_page_template = (vm_address_t)&ffi_closure_trampoline_table_page;
|
207
|
+
#ifdef __arm__
|
208
|
+
/* ffi_closure_trampoline_table_page can be thumb-biased on some ARM archs */
|
209
|
+
trampoline_page_template &= ~1UL;
|
210
|
+
#endif
|
211
|
+
kt = vm_remap (mach_task_self (), &trampoline_page, PAGE_MAX_SIZE, 0x0,
|
212
|
+
VM_FLAGS_OVERWRITE, mach_task_self (), trampoline_page_template,
|
213
|
+
FALSE, &cur_prot, &max_prot, VM_INHERIT_SHARE);
|
214
|
+
if (kt != KERN_SUCCESS)
|
116
215
|
{
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
/* Try to allocate two pages */
|
121
|
-
kt =
|
122
|
-
vm_allocate (mach_task_self (), &config_page, PAGE_MAX_SIZE * 2,
|
123
|
-
VM_FLAGS_ANYWHERE);
|
124
|
-
if (kt != KERN_SUCCESS)
|
125
|
-
{
|
126
|
-
fprintf (stderr, "vm_allocate() failure: %d at %s:%d\n", kt,
|
127
|
-
__FILE__, __LINE__);
|
128
|
-
break;
|
129
|
-
}
|
130
|
-
|
131
|
-
/* Now drop the second half of the allocation to make room for the trampoline table */
|
132
|
-
vm_address_t trampoline_page = config_page + PAGE_MAX_SIZE;
|
133
|
-
kt = vm_deallocate (mach_task_self (), trampoline_page, PAGE_MAX_SIZE);
|
134
|
-
if (kt != KERN_SUCCESS)
|
135
|
-
{
|
136
|
-
fprintf (stderr, "vm_deallocate() failure: %d at %s:%d\n", kt,
|
137
|
-
__FILE__, __LINE__);
|
138
|
-
break;
|
139
|
-
}
|
216
|
+
vm_deallocate (mach_task_self (), config_page, PAGE_MAX_SIZE * 2);
|
217
|
+
return NULL;
|
218
|
+
}
|
140
219
|
|
141
|
-
|
142
|
-
|
143
|
-
|
220
|
+
/* We have valid trampoline and config pages */
|
221
|
+
table = calloc (1, sizeof (ffi_trampoline_table));
|
222
|
+
table->free_count = FFI_TRAMPOLINE_COUNT;
|
223
|
+
table->config_page = config_page;
|
224
|
+
table->trampoline_page = trampoline_page;
|
144
225
|
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
trampoline_page_template &= ~1UL;
|
149
|
-
#endif
|
226
|
+
/* Create and initialize the free list */
|
227
|
+
table->free_list_pool =
|
228
|
+
calloc (FFI_TRAMPOLINE_COUNT, sizeof (ffi_trampoline_table_entry));
|
150
229
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
230
|
+
for (i = 0; i < table->free_count; i++)
|
231
|
+
{
|
232
|
+
ffi_trampoline_table_entry *entry = &table->free_list_pool[i];
|
233
|
+
entry->trampoline =
|
234
|
+
(void *) (table->trampoline_page + (i * FFI_TRAMPOLINE_SIZE));
|
155
235
|
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
/* Log unexpected failures */
|
160
|
-
if (kt != KERN_NO_SPACE)
|
161
|
-
{
|
162
|
-
fprintf (stderr, "vm_remap() failure: %d at %s:%d\n", kt,
|
163
|
-
__FILE__, __LINE__);
|
164
|
-
}
|
165
|
-
|
166
|
-
vm_deallocate (mach_task_self (), config_page, PAGE_SIZE);
|
167
|
-
continue;
|
168
|
-
}
|
236
|
+
if (i < table->free_count - 1)
|
237
|
+
entry->next = &table->free_list_pool[i + 1];
|
238
|
+
}
|
169
239
|
|
170
|
-
|
171
|
-
table = calloc (1, sizeof (ffi_trampoline_table));
|
172
|
-
table->free_count = FFI_TRAMPOLINE_COUNT;
|
173
|
-
table->config_page = config_page;
|
174
|
-
table->trampoline_page = trampoline_page;
|
240
|
+
table->free_list = table->free_list_pool;
|
175
241
|
|
176
|
-
|
177
|
-
|
178
|
-
calloc (FFI_TRAMPOLINE_COUNT, sizeof (ffi_trampoline_table_entry));
|
242
|
+
return table;
|
243
|
+
}
|
179
244
|
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
245
|
+
static void
|
246
|
+
ffi_trampoline_table_free (ffi_trampoline_table *table)
|
247
|
+
{
|
248
|
+
/* Remove from the list */
|
249
|
+
if (table->prev != NULL)
|
250
|
+
table->prev->next = table->next;
|
186
251
|
|
187
|
-
|
188
|
-
|
189
|
-
}
|
252
|
+
if (table->next != NULL)
|
253
|
+
table->next->prev = table->prev;
|
190
254
|
|
191
|
-
|
192
|
-
|
255
|
+
/* Deallocate pages */
|
256
|
+
vm_deallocate (mach_task_self (), table->config_page, PAGE_MAX_SIZE * 2);
|
193
257
|
|
194
|
-
|
258
|
+
/* Deallocate free list */
|
259
|
+
free (table->free_list_pool);
|
260
|
+
free (table);
|
195
261
|
}
|
196
262
|
|
197
263
|
void *
|
@@ -261,29 +327,7 @@ ffi_closure_free (void *ptr)
|
|
261
327
|
if (table->free_count == FFI_TRAMPOLINE_COUNT
|
262
328
|
&& ffi_trampoline_tables != table)
|
263
329
|
{
|
264
|
-
|
265
|
-
if (table->prev != NULL)
|
266
|
-
table->prev->next = table->next;
|
267
|
-
|
268
|
-
if (table->next != NULL)
|
269
|
-
table->next->prev = table->prev;
|
270
|
-
|
271
|
-
/* Deallocate pages */
|
272
|
-
kern_return_t kt;
|
273
|
-
kt = vm_deallocate (mach_task_self (), table->config_page, PAGE_SIZE);
|
274
|
-
if (kt != KERN_SUCCESS)
|
275
|
-
fprintf (stderr, "vm_deallocate() failure: %d at %s:%d\n", kt,
|
276
|
-
__FILE__, __LINE__);
|
277
|
-
|
278
|
-
kt =
|
279
|
-
vm_deallocate (mach_task_self (), table->trampoline_page, PAGE_SIZE);
|
280
|
-
if (kt != KERN_SUCCESS)
|
281
|
-
fprintf (stderr, "vm_deallocate() failure: %d at %s:%d\n", kt,
|
282
|
-
__FILE__, __LINE__);
|
283
|
-
|
284
|
-
/* Deallocate free list */
|
285
|
-
free (table->free_list_pool);
|
286
|
-
free (table);
|
330
|
+
ffi_trampoline_table_free (table);
|
287
331
|
}
|
288
332
|
else if (ffi_trampoline_tables != table)
|
289
333
|
{
|
@@ -538,7 +582,7 @@ open_temp_exec_file_dir (const char *dir)
|
|
538
582
|
}
|
539
583
|
#endif
|
540
584
|
|
541
|
-
lendir = strlen (dir);
|
585
|
+
lendir = (int) strlen (dir);
|
542
586
|
tempname = __builtin_alloca (lendir + sizeof (suffix));
|
543
587
|
|
544
588
|
if (!tempname)
|
@@ -888,3 +932,5 @@ ffi_closure_free (void *ptr)
|
|
888
932
|
|
889
933
|
# endif /* ! FFI_MMAP_EXEC_WRIT */
|
890
934
|
#endif /* FFI_CLOSURES */
|
935
|
+
|
936
|
+
#endif /* NetBSD with PROT_MPROTECT */
|