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.

Files changed (151) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +3 -0
  3. data.tar.gz.sig +0 -0
  4. data/.gitignore +22 -0
  5. data/.gitmodules +3 -0
  6. data/.travis.yml +52 -0
  7. data/.yardopts +5 -0
  8. data/Gemfile +15 -0
  9. data/{spec/ffi/LICENSE.SPECS → LICENSE.SPECS} +1 -1
  10. data/README.md +1 -1
  11. data/Rakefile +28 -3
  12. data/appveyor.yml +22 -0
  13. data/ext/ffi_c/Call.c +1 -22
  14. data/ext/ffi_c/Call.h +0 -9
  15. data/ext/ffi_c/Closure.c +54 -0
  16. data/ext/ffi_c/{ClosurePool.h → Closure.h} +13 -23
  17. data/ext/ffi_c/Function.c +16 -25
  18. data/ext/ffi_c/Function.h +1 -2
  19. data/ext/ffi_c/FunctionInfo.c +0 -4
  20. data/ext/ffi_c/MethodHandle.c +33 -268
  21. data/ext/ffi_c/extconf.rb +3 -3
  22. data/ext/ffi_c/ffi.c +2 -2
  23. data/ext/ffi_c/libffi.bsd.mk +3 -3
  24. data/ext/ffi_c/libffi.darwin.mk +1 -1
  25. data/ext/ffi_c/libffi.gnu.mk +1 -1
  26. data/ext/ffi_c/libffi.mk +2 -2
  27. data/ext/ffi_c/libffi.vc.mk +1 -1
  28. data/ext/ffi_c/libffi.vc64.mk +1 -1
  29. data/ext/ffi_c/libffi/.appveyor.yml +48 -0
  30. data/ext/ffi_c/libffi/.gitignore +36 -0
  31. data/ext/ffi_c/libffi/.travis.yml +30 -0
  32. data/ext/ffi_c/libffi/.travis/install.sh +14 -0
  33. data/ext/ffi_c/libffi/Makefile.am +5 -3
  34. data/ext/ffi_c/libffi/acinclude.m4 +6 -0
  35. data/ext/ffi_c/libffi/autogen.sh +1 -1
  36. data/ext/ffi_c/libffi/config.guess +1466 -0
  37. data/ext/ffi_c/libffi/config.sub +1836 -0
  38. data/ext/ffi_c/libffi/configure.ac +2 -2
  39. data/ext/ffi_c/libffi/configure.host +15 -3
  40. data/ext/ffi_c/libffi/generate-darwin-source-and-headers.py +11 -15
  41. data/ext/ffi_c/libffi/include/ffi.h.in +6 -1
  42. data/ext/ffi_c/libffi/libffi.xcodeproj/project.pbxproj +465 -59
  43. data/ext/ffi_c/libffi/src/aarch64/ffi.c +33 -10
  44. data/ext/ffi_c/libffi/src/aarch64/sysv.S +2 -2
  45. data/ext/ffi_c/libffi/src/arm/ffi.c +12 -1
  46. data/ext/ffi_c/libffi/src/arm/sysv.S +1 -1
  47. data/ext/ffi_c/libffi/src/closures.c +143 -97
  48. data/ext/ffi_c/libffi/src/ia64/unix.S +2 -0
  49. data/ext/ffi_c/libffi/src/mips/ffi.c +8 -0
  50. data/ext/ffi_c/libffi/src/mips/ffitarget.h +1 -1
  51. data/ext/ffi_c/libffi/src/mips/n32.S +2 -0
  52. data/ext/ffi_c/libffi/src/powerpc/aix.S +239 -1
  53. data/ext/ffi_c/libffi/src/powerpc/aix_closure.S +250 -3
  54. data/ext/ffi_c/libffi/src/powerpc/ffi_darwin.c +86 -5
  55. data/ext/ffi_c/libffi/src/powerpc/ffitarget.h +3 -0
  56. data/ext/ffi_c/libffi/src/x86/ffi.c +3 -1
  57. data/ext/ffi_c/libffi/src/x86/ffi64.c +26 -5
  58. data/ext/ffi_c/libffi/src/x86/sysv.S +2 -2
  59. data/ext/ffi_c/libffi/src/x86/unix64.S +1 -1
  60. data/ext/ffi_c/libffi/src/x86/win64.S +1 -1
  61. data/ext/ffi_c/libffi/testsuite/Makefile.am +2 -1
  62. data/ext/ffi_c/libffi/testsuite/lib/libffi.exp +2 -1
  63. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3float.c +95 -0
  64. data/ffi.gemspec +14 -1
  65. data/lib/ffi/library.rb +1 -1
  66. data/lib/ffi/version.rb +1 -1
  67. data/samples/getlogin.rb +8 -0
  68. data/samples/getpid.rb +8 -0
  69. data/samples/gettimeofday.rb +18 -0
  70. data/samples/hello.rb +7 -0
  71. data/samples/inotify.rb +60 -0
  72. data/samples/pty.rb +76 -0
  73. data/samples/qsort.rb +21 -0
  74. data/samples/sample_helper.rb +6 -0
  75. metadata +59 -81
  76. metadata.gz.sig +0 -0
  77. data/ext/ffi_c/ClosurePool.c +0 -283
  78. data/gen/Rakefile +0 -30
  79. data/libtest/Benchmark.c +0 -52
  80. data/libtest/BoolTest.c +0 -34
  81. data/libtest/BufferTest.c +0 -31
  82. data/libtest/ClosureTest.c +0 -205
  83. data/libtest/EnumTest.c +0 -51
  84. data/libtest/FunctionTest.c +0 -70
  85. data/libtest/GNUmakefile +0 -149
  86. data/libtest/GlobalVariable.c +0 -62
  87. data/libtest/LastErrorTest.c +0 -21
  88. data/libtest/NumberTest.c +0 -132
  89. data/libtest/PointerTest.c +0 -63
  90. data/libtest/ReferenceTest.c +0 -23
  91. data/libtest/StringTest.c +0 -34
  92. data/libtest/StructTest.c +0 -243
  93. data/libtest/UnionTest.c +0 -43
  94. data/libtest/VariadicTest.c +0 -99
  95. data/spec/ffi/async_callback_spec.rb +0 -35
  96. data/spec/ffi/bitmask_spec.rb +0 -575
  97. data/spec/ffi/bool_spec.rb +0 -32
  98. data/spec/ffi/buffer_spec.rb +0 -279
  99. data/spec/ffi/callback_spec.rb +0 -773
  100. data/spec/ffi/custom_param_type.rb +0 -37
  101. data/spec/ffi/custom_type_spec.rb +0 -74
  102. data/spec/ffi/dup_spec.rb +0 -52
  103. data/spec/ffi/enum_spec.rb +0 -423
  104. data/spec/ffi/errno_spec.rb +0 -20
  105. data/spec/ffi/ffi_spec.rb +0 -28
  106. data/spec/ffi/fixtures/Benchmark.c +0 -52
  107. data/spec/ffi/fixtures/BitmaskTest.c +0 -51
  108. data/spec/ffi/fixtures/BoolTest.c +0 -34
  109. data/spec/ffi/fixtures/BufferTest.c +0 -31
  110. data/spec/ffi/fixtures/ClosureTest.c +0 -205
  111. data/spec/ffi/fixtures/EnumTest.c +0 -51
  112. data/spec/ffi/fixtures/FunctionTest.c +0 -142
  113. data/spec/ffi/fixtures/GNUmakefile +0 -149
  114. data/spec/ffi/fixtures/GlobalVariable.c +0 -62
  115. data/spec/ffi/fixtures/LastErrorTest.c +0 -21
  116. data/spec/ffi/fixtures/NumberTest.c +0 -132
  117. data/spec/ffi/fixtures/PipeHelper.h +0 -21
  118. data/spec/ffi/fixtures/PipeHelperPosix.c +0 -41
  119. data/spec/ffi/fixtures/PipeHelperWindows.c +0 -72
  120. data/spec/ffi/fixtures/PointerTest.c +0 -63
  121. data/spec/ffi/fixtures/ReferenceTest.c +0 -23
  122. data/spec/ffi/fixtures/StringTest.c +0 -34
  123. data/spec/ffi/fixtures/StructTest.c +0 -243
  124. data/spec/ffi/fixtures/UnionTest.c +0 -43
  125. data/spec/ffi/fixtures/VariadicTest.c +0 -99
  126. data/spec/ffi/fixtures/classes.rb +0 -438
  127. data/spec/ffi/function_spec.rb +0 -97
  128. data/spec/ffi/io_spec.rb +0 -16
  129. data/spec/ffi/library_spec.rb +0 -286
  130. data/spec/ffi/long_double.rb +0 -30
  131. data/spec/ffi/managed_struct_spec.rb +0 -68
  132. data/spec/ffi/memorypointer_spec.rb +0 -78
  133. data/spec/ffi/number_spec.rb +0 -247
  134. data/spec/ffi/platform_spec.rb +0 -114
  135. data/spec/ffi/pointer_spec.rb +0 -285
  136. data/spec/ffi/rbx/attach_function_spec.rb +0 -34
  137. data/spec/ffi/rbx/memory_pointer_spec.rb +0 -198
  138. data/spec/ffi/rbx/spec_helper.rb +0 -6
  139. data/spec/ffi/rbx/struct_spec.rb +0 -18
  140. data/spec/ffi/spec_helper.rb +0 -93
  141. data/spec/ffi/string_spec.rb +0 -118
  142. data/spec/ffi/strptr_spec.rb +0 -50
  143. data/spec/ffi/struct_by_ref_spec.rb +0 -43
  144. data/spec/ffi/struct_callback_spec.rb +0 -69
  145. data/spec/ffi/struct_initialize_spec.rb +0 -35
  146. data/spec/ffi/struct_packed_spec.rb +0 -50
  147. data/spec/ffi/struct_spec.rb +0 -882
  148. data/spec/ffi/typedef_spec.rb +0 -91
  149. data/spec/ffi/union_spec.rb +0 -67
  150. data/spec/ffi/variadic_spec.rb +0 -132
  151. 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 has been copied to memory, and
687
+ bytes, then the argument is copied to memory, and
668
688
  the argument is replaced by a pointer to the copy. */
669
- a = &avalue[i];
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, [x2, #8] /* S3 */
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
 
@@ -356,7 +356,7 @@ ARM_FUNC_END(ffi_closure_ret)
356
356
  #if FFI_EXEC_TRAMPOLINE_TABLE
357
357
 
358
358
  #ifdef __MACH__
359
- #include <mach/vm_param.h>
359
+ #include <mach/machine/vm_param.h>
360
360
 
361
361
  .align PAGE_MAX_SHIFT
362
362
  ARM_FUNC_START(ffi_closure_trampoline_table_page)
@@ -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
- # ifdef __linux__
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 = NULL;
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
- /* Loop until we can allocate two contiguous pages */
115
- while (table == NULL)
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
- vm_address_t config_page = 0x0;
118
- kern_return_t kt;
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
- /* Remap the trampoline table to directly follow the config page */
142
- vm_prot_t cur_prot;
143
- vm_prot_t max_prot;
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
- vm_address_t trampoline_page_template = (vm_address_t)&ffi_closure_trampoline_table_page;
146
- #ifdef __arm__
147
- /* ffi_closure_trampoline_table_page can be thumb-biased on some ARM archs */
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
- kt =
152
- vm_remap (mach_task_self (), &trampoline_page, PAGE_MAX_SIZE, 0x0, FALSE,
153
- mach_task_self (), trampoline_page_template, FALSE,
154
- &cur_prot, &max_prot, VM_INHERIT_SHARE);
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
- /* If we lost access to the destination trampoline page, drop our config allocation mapping and retry */
157
- if (kt != KERN_SUCCESS)
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
- /* We have valid trampoline and config pages */
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
- /* Create and initialize the free list */
177
- table->free_list_pool =
178
- calloc (FFI_TRAMPOLINE_COUNT, sizeof (ffi_trampoline_table_entry));
242
+ return table;
243
+ }
179
244
 
180
- uint16_t i;
181
- for (i = 0; i < table->free_count; i++)
182
- {
183
- ffi_trampoline_table_entry *entry = &table->free_list_pool[i];
184
- entry->trampoline =
185
- (void *) (table->trampoline_page + (i * FFI_TRAMPOLINE_SIZE));
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
- if (i < table->free_count - 1)
188
- entry->next = &table->free_list_pool[i + 1];
189
- }
252
+ if (table->next != NULL)
253
+ table->next->prev = table->prev;
190
254
 
191
- table->free_list = table->free_list_pool;
192
- }
255
+ /* Deallocate pages */
256
+ vm_deallocate (mach_task_self (), table->config_page, PAGE_MAX_SIZE * 2);
193
257
 
194
- return table;
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
- /* Remove from the list */
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 */