ffi 1.0.0 → 1.17.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (694) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +4 -0
  3. data/CHANGELOG.md +465 -0
  4. data/COPYING +49 -0
  5. data/Gemfile +21 -0
  6. data/LICENSE +21 -11
  7. data/LICENSE.SPECS +22 -0
  8. data/README.md +137 -0
  9. data/Rakefile +165 -148
  10. data/ext/ffi_c/AbstractMemory.c +716 -97
  11. data/ext/ffi_c/AbstractMemory.h +38 -17
  12. data/ext/ffi_c/ArrayType.c +102 -33
  13. data/ext/ffi_c/ArrayType.h +20 -18
  14. data/ext/ffi_c/Buffer.c +229 -54
  15. data/ext/ffi_c/Call.c +211 -100
  16. data/ext/ffi_c/Call.h +46 -28
  17. data/ext/ffi_c/ClosurePool.c +110 -81
  18. data/ext/ffi_c/ClosurePool.h +31 -1
  19. data/ext/ffi_c/DynamicLibrary.c +216 -54
  20. data/ext/ffi_c/DynamicLibrary.h +76 -0
  21. data/ext/ffi_c/Function.c +527 -164
  22. data/ext/ffi_c/Function.h +24 -20
  23. data/ext/ffi_c/FunctionInfo.c +151 -50
  24. data/ext/ffi_c/LastError.c +112 -28
  25. data/ext/ffi_c/LastError.h +29 -0
  26. data/ext/ffi_c/LongDouble.c +65 -0
  27. data/ext/ffi_c/LongDouble.h +47 -0
  28. data/ext/ffi_c/MappedType.c +107 -42
  29. data/ext/ffi_c/MappedType.h +20 -20
  30. data/ext/ffi_c/MemoryPointer.c +108 -46
  31. data/ext/ffi_c/MemoryPointer.h +33 -4
  32. data/ext/ffi_c/MethodHandle.c +71 -67
  33. data/ext/ffi_c/MethodHandle.h +26 -23
  34. data/ext/ffi_c/Platform.c +42 -25
  35. data/ext/ffi_c/Platform.h +32 -3
  36. data/ext/ffi_c/Pointer.c +324 -51
  37. data/ext/ffi_c/Pointer.h +29 -18
  38. data/ext/ffi_c/Struct.c +434 -161
  39. data/ext/ffi_c/Struct.h +47 -27
  40. data/ext/ffi_c/StructByValue.c +74 -37
  41. data/ext/ffi_c/StructByValue.h +20 -18
  42. data/ext/ffi_c/StructLayout.c +358 -87
  43. data/ext/ffi_c/Thread.c +129 -0
  44. data/ext/ffi_c/Thread.h +76 -0
  45. data/ext/ffi_c/Type.c +241 -76
  46. data/ext/ffi_c/Type.h +27 -11
  47. data/ext/ffi_c/Types.c +54 -34
  48. data/ext/ffi_c/Types.h +24 -24
  49. data/ext/ffi_c/Variadic.c +151 -55
  50. data/ext/ffi_c/compat.h +48 -38
  51. data/ext/ffi_c/extconf.rb +106 -34
  52. data/ext/ffi_c/ffi.c +35 -26
  53. data/ext/ffi_c/libffi/.allow-ai-service +0 -0
  54. data/ext/ffi_c/libffi/.appveyor/site.exp +16 -0
  55. data/ext/ffi_c/libffi/.appveyor/unix-noexec.exp +7 -0
  56. data/ext/ffi_c/libffi/.appveyor.yml +84 -0
  57. data/ext/ffi_c/libffi/.ci/ar-lib +270 -0
  58. data/ext/ffi_c/libffi/.ci/bfin-sim.exp +58 -0
  59. data/ext/ffi_c/libffi/.ci/build-cross-in-container.sh +18 -0
  60. data/ext/ffi_c/libffi/.ci/build-in-container.sh +10 -0
  61. data/ext/ffi_c/libffi/.ci/build.sh +124 -0
  62. data/ext/ffi_c/libffi/.ci/compile +351 -0
  63. data/ext/ffi_c/libffi/.ci/install.sh +78 -0
  64. data/ext/ffi_c/libffi/.ci/m32r-sim.exp +58 -0
  65. data/ext/ffi_c/libffi/.ci/moxie-sim.exp +60 -0
  66. data/ext/ffi_c/libffi/.ci/msvs-detect +1103 -0
  67. data/ext/ffi_c/libffi/.ci/or1k-sim.exp +58 -0
  68. data/ext/ffi_c/libffi/.ci/powerpc-eabisim.exp +58 -0
  69. data/ext/ffi_c/libffi/.ci/site.exp +29 -0
  70. data/ext/ffi_c/libffi/.ci/wine-sim.exp +55 -0
  71. data/ext/ffi_c/libffi/.circleci/config.yml +156 -0
  72. data/ext/ffi_c/libffi/.gitattributes +4 -0
  73. data/ext/ffi_c/libffi/.github/issue_template.md +10 -0
  74. data/ext/ffi_c/libffi/.github/workflows/build.yml +479 -0
  75. data/ext/ffi_c/libffi/.github/workflows/emscripten.yml +172 -0
  76. data/ext/ffi_c/libffi/.gitignore +46 -0
  77. data/ext/ffi_c/libffi/{ChangeLog → ChangeLog.old} +6528 -3180
  78. data/ext/ffi_c/libffi/LICENSE +3 -3
  79. data/ext/ffi_c/libffi/LICENSE-BUILDTOOLS +353 -0
  80. data/ext/ffi_c/libffi/Makefile.am +132 -162
  81. data/ext/ffi_c/libffi/Makefile.in +1339 -1003
  82. data/ext/ffi_c/libffi/README.md +531 -0
  83. data/ext/ffi_c/libffi/acinclude.m4 +289 -4
  84. data/ext/ffi_c/libffi/autogen.sh +2 -0
  85. data/ext/ffi_c/libffi/compile +227 -21
  86. data/ext/ffi_c/libffi/config.guess +1034 -778
  87. data/ext/ffi_c/libffi/config.sub +1394 -1204
  88. data/ext/ffi_c/libffi/configure +14327 -8503
  89. data/ext/ffi_c/libffi/configure.ac +294 -247
  90. data/ext/ffi_c/libffi/configure.host +330 -4
  91. data/ext/ffi_c/libffi/doc/Makefile.am +3 -0
  92. data/ext/ffi_c/libffi/doc/Makefile.in +818 -0
  93. data/ext/ffi_c/libffi/doc/libffi.texi +572 -67
  94. data/ext/ffi_c/libffi/doc/version.texi +4 -4
  95. data/ext/ffi_c/libffi/fficonfig.h.in +53 -46
  96. data/ext/ffi_c/libffi/generate-darwin-source-and-headers.py +312 -0
  97. data/ext/ffi_c/libffi/include/Makefile.am +3 -3
  98. data/ext/ffi_c/libffi/include/Makefile.in +219 -79
  99. data/ext/ffi_c/libffi/include/ffi.h.in +230 -111
  100. data/ext/ffi_c/libffi/include/ffi_cfi.h +76 -0
  101. data/ext/ffi_c/libffi/include/ffi_common.h +78 -16
  102. data/ext/ffi_c/libffi/include/tramp.h +45 -0
  103. data/ext/ffi_c/libffi/install-sh +402 -184
  104. data/ext/ffi_c/libffi/libffi.map.in +81 -0
  105. data/ext/ffi_c/libffi/libffi.pc.in +3 -2
  106. data/ext/ffi_c/libffi/libffi.xcodeproj/project.pbxproj +997 -0
  107. data/ext/ffi_c/libffi/libtool-ldflags +106 -0
  108. data/ext/ffi_c/libffi/libtool-version +2 -2
  109. data/ext/ffi_c/libffi/ltmain.sh +5752 -2722
  110. data/ext/ffi_c/libffi/m4/asmcfi.m4 +13 -0
  111. data/ext/ffi_c/libffi/m4/ax_append_flag.m4 +50 -0
  112. data/ext/ffi_c/libffi/m4/ax_cc_maxopt.m4 +198 -0
  113. data/ext/ffi_c/libffi/m4/ax_cflags_warn_all.m4 +158 -0
  114. data/ext/ffi_c/libffi/m4/ax_check_compile_flag.m4 +53 -0
  115. data/ext/ffi_c/libffi/m4/ax_compiler_vendor.m4 +119 -0
  116. data/ext/ffi_c/libffi/m4/ax_configure_args.m4 +49 -0
  117. data/ext/ffi_c/libffi/m4/ax_enable_builddir.m4 +302 -0
  118. data/ext/ffi_c/libffi/m4/ax_gcc_archflag.m4 +267 -0
  119. data/ext/ffi_c/libffi/m4/ax_gcc_x86_cpuid.m4 +89 -0
  120. data/ext/ffi_c/libffi/m4/ax_prepend_flag.m4 +51 -0
  121. data/ext/ffi_c/libffi/m4/ax_require_defined.m4 +37 -0
  122. data/ext/ffi_c/libffi/make_sunver.pl +333 -0
  123. data/ext/ffi_c/libffi/man/Makefile.am +2 -2
  124. data/ext/ffi_c/libffi/man/Makefile.in +174 -57
  125. data/ext/ffi_c/libffi/man/ffi.3 +10 -0
  126. data/ext/ffi_c/libffi/man/ffi_prep_cif.3 +6 -4
  127. data/ext/ffi_c/libffi/man/ffi_prep_cif_var.3 +73 -0
  128. data/ext/ffi_c/libffi/missing +155 -300
  129. data/ext/ffi_c/libffi/msvc_build/aarch64/Ffi_staticLib.sln +33 -0
  130. data/ext/ffi_c/libffi/msvc_build/aarch64/Ffi_staticLib.vcxproj +130 -0
  131. data/ext/ffi_c/libffi/msvc_build/aarch64/Ffi_staticLib.vcxproj.filters +57 -0
  132. data/ext/ffi_c/libffi/msvc_build/aarch64/Ffi_staticLib.vcxproj.user +4 -0
  133. data/ext/ffi_c/libffi/msvc_build/aarch64/aarch64_include/ffi.h +511 -0
  134. data/ext/ffi_c/libffi/msvc_build/aarch64/aarch64_include/fficonfig.h +219 -0
  135. data/ext/ffi_c/libffi/msvcc.sh +353 -0
  136. data/ext/ffi_c/libffi/src/aarch64/ffi.c +1142 -0
  137. data/ext/ffi_c/libffi/src/aarch64/ffitarget.h +97 -0
  138. data/ext/ffi_c/libffi/src/aarch64/internal.h +100 -0
  139. data/ext/ffi_c/libffi/src/aarch64/sysv.S +695 -0
  140. data/ext/ffi_c/libffi/src/aarch64/win64_armasm.S +506 -0
  141. data/ext/ffi_c/libffi/src/alpha/ffi.c +335 -98
  142. data/ext/ffi_c/libffi/src/alpha/ffitarget.h +10 -1
  143. data/ext/ffi_c/libffi/src/alpha/internal.h +23 -0
  144. data/ext/ffi_c/libffi/src/alpha/osf.S +162 -246
  145. data/ext/ffi_c/libffi/src/arc/arcompact.S +210 -0
  146. data/ext/ffi_c/libffi/src/arc/ffi.c +443 -0
  147. data/ext/ffi_c/libffi/src/arc/ffitarget.h +67 -0
  148. data/ext/ffi_c/libffi/src/arm/ffi.c +806 -194
  149. data/ext/ffi_c/libffi/src/arm/ffitarget.h +43 -3
  150. data/ext/ffi_c/libffi/src/arm/internal.h +17 -0
  151. data/ext/ffi_c/libffi/src/arm/sysv.S +381 -231
  152. data/ext/ffi_c/libffi/src/arm/sysv_msvc_arm32.S +311 -0
  153. data/ext/ffi_c/libffi/src/avr32/ffi.c +4 -2
  154. data/ext/ffi_c/libffi/src/avr32/ffitarget.h +8 -3
  155. data/ext/ffi_c/libffi/src/bfin/ffi.c +196 -0
  156. data/ext/ffi_c/libffi/src/bfin/ffitarget.h +43 -0
  157. data/ext/ffi_c/libffi/src/bfin/sysv.S +179 -0
  158. data/ext/ffi_c/libffi/src/closures.c +574 -100
  159. data/ext/ffi_c/libffi/src/cris/ffi.c +11 -8
  160. data/ext/ffi_c/libffi/src/cris/ffitarget.h +8 -3
  161. data/ext/ffi_c/libffi/src/csky/ffi.c +395 -0
  162. data/ext/ffi_c/libffi/src/csky/ffitarget.h +63 -0
  163. data/ext/ffi_c/libffi/src/csky/sysv.S +371 -0
  164. data/ext/ffi_c/libffi/src/debug.c +8 -3
  165. data/ext/ffi_c/libffi/src/dlmalloc.c +89 -17
  166. data/ext/ffi_c/libffi/src/frv/ffi.c +2 -2
  167. data/ext/ffi_c/libffi/src/frv/ffitarget.h +8 -7
  168. data/ext/ffi_c/libffi/src/ia64/ffi.c +48 -12
  169. data/ext/ffi_c/libffi/src/ia64/ffitarget.h +10 -4
  170. data/ext/ffi_c/libffi/src/ia64/unix.S +28 -3
  171. data/ext/ffi_c/libffi/src/java_raw_api.c +24 -6
  172. data/ext/ffi_c/libffi/src/kvx/asm.h +5 -0
  173. data/ext/ffi_c/libffi/src/kvx/ffi.c +273 -0
  174. data/ext/ffi_c/libffi/src/kvx/ffitarget.h +75 -0
  175. data/ext/ffi_c/libffi/src/kvx/sysv.S +127 -0
  176. data/ext/ffi_c/libffi/src/loongarch64/ffi.c +624 -0
  177. data/ext/ffi_c/libffi/src/loongarch64/ffitarget.h +82 -0
  178. data/ext/ffi_c/libffi/src/loongarch64/sysv.S +327 -0
  179. data/ext/ffi_c/libffi/src/m32r/ffi.c +32 -15
  180. data/ext/ffi_c/libffi/src/m32r/ffitarget.h +8 -3
  181. data/ext/ffi_c/libffi/src/m68k/ffi.c +97 -13
  182. data/ext/ffi_c/libffi/src/m68k/ffitarget.h +8 -3
  183. data/ext/ffi_c/libffi/src/m68k/sysv.S +148 -25
  184. data/ext/ffi_c/libffi/src/m88k/ffi.c +400 -0
  185. data/ext/ffi_c/libffi/src/m88k/ffitarget.h +49 -0
  186. data/ext/ffi_c/libffi/src/m88k/obsd.S +209 -0
  187. data/ext/ffi_c/libffi/src/metag/ffi.c +330 -0
  188. data/ext/ffi_c/libffi/src/metag/ffitarget.h +53 -0
  189. data/ext/ffi_c/libffi/src/metag/sysv.S +311 -0
  190. data/ext/ffi_c/libffi/src/microblaze/ffi.c +321 -0
  191. data/ext/ffi_c/libffi/src/microblaze/ffitarget.h +53 -0
  192. data/ext/ffi_c/libffi/src/microblaze/sysv.S +302 -0
  193. data/ext/ffi_c/libffi/src/mips/ffi.c +392 -104
  194. data/ext/ffi_c/libffi/src/mips/ffitarget.h +40 -24
  195. data/ext/ffi_c/libffi/src/mips/n32.S +325 -93
  196. data/ext/ffi_c/libffi/src/mips/o32.S +211 -31
  197. data/ext/ffi_c/libffi/src/moxie/eabi.S +101 -0
  198. data/ext/ffi_c/libffi/src/moxie/ffi.c +310 -0
  199. data/ext/ffi_c/libffi/src/moxie/ffitarget.h +52 -0
  200. data/ext/ffi_c/libffi/src/nios2/ffi.c +304 -0
  201. data/ext/ffi_c/libffi/src/nios2/ffitarget.h +52 -0
  202. data/ext/ffi_c/libffi/src/nios2/sysv.S +136 -0
  203. data/ext/ffi_c/libffi/src/or1k/ffi.c +341 -0
  204. data/ext/ffi_c/libffi/src/or1k/ffitarget.h +58 -0
  205. data/ext/ffi_c/libffi/src/or1k/sysv.S +107 -0
  206. data/ext/ffi_c/libffi/src/pa/ffi.c +68 -111
  207. data/ext/ffi_c/libffi/src/pa/ffi64.c +614 -0
  208. data/ext/ffi_c/libffi/src/pa/ffitarget.h +34 -17
  209. data/ext/ffi_c/libffi/src/pa/hpux32.S +87 -38
  210. data/ext/ffi_c/libffi/src/pa/hpux64.S +681 -0
  211. data/ext/ffi_c/libffi/src/pa/linux.S +109 -39
  212. data/ext/ffi_c/libffi/src/powerpc/aix.S +250 -8
  213. data/ext/ffi_c/libffi/src/powerpc/aix_closure.S +255 -4
  214. data/ext/ffi_c/libffi/src/powerpc/asm.h +3 -3
  215. data/ext/ffi_c/libffi/src/powerpc/darwin.S +211 -78
  216. data/ext/ffi_c/libffi/src/powerpc/darwin_closure.S +356 -102
  217. data/ext/ffi_c/libffi/src/powerpc/ffi.c +108 -1375
  218. data/ext/ffi_c/libffi/src/powerpc/ffi_darwin.c +746 -210
  219. data/ext/ffi_c/libffi/src/powerpc/ffi_linux64.c +1153 -0
  220. data/ext/ffi_c/libffi/src/powerpc/ffi_powerpc.h +105 -0
  221. data/ext/ffi_c/libffi/src/powerpc/ffi_sysv.c +923 -0
  222. data/ext/ffi_c/libffi/src/powerpc/ffitarget.h +126 -48
  223. data/ext/ffi_c/libffi/src/powerpc/linux64.S +191 -85
  224. data/ext/ffi_c/libffi/src/powerpc/linux64_closure.S +438 -108
  225. data/ext/ffi_c/libffi/src/powerpc/ppc_closure.S +138 -68
  226. data/ext/ffi_c/libffi/src/powerpc/sysv.S +73 -119
  227. data/ext/ffi_c/libffi/src/powerpc/t-aix +5 -0
  228. data/ext/ffi_c/libffi/src/prep_cif.c +141 -32
  229. data/ext/ffi_c/libffi/src/raw_api.c +18 -5
  230. data/ext/ffi_c/libffi/src/riscv/ffi.c +514 -0
  231. data/ext/ffi_c/libffi/src/riscv/ffitarget.h +69 -0
  232. data/ext/ffi_c/libffi/src/riscv/sysv.S +293 -0
  233. data/ext/ffi_c/libffi/src/s390/ffi.c +294 -318
  234. data/ext/ffi_c/libffi/src/s390/ffitarget.h +13 -3
  235. data/ext/ffi_c/libffi/src/s390/internal.h +11 -0
  236. data/ext/ffi_c/libffi/src/s390/sysv.S +257 -366
  237. data/ext/ffi_c/libffi/src/sh/ffi.c +4 -3
  238. data/ext/ffi_c/libffi/src/sh/ffitarget.h +8 -3
  239. data/ext/ffi_c/libffi/src/sh64/ffi.c +3 -2
  240. data/ext/ffi_c/libffi/src/sh64/ffitarget.h +8 -3
  241. data/ext/ffi_c/libffi/src/sparc/ffi.c +334 -491
  242. data/ext/ffi_c/libffi/src/sparc/ffi64.c +630 -0
  243. data/ext/ffi_c/libffi/src/sparc/ffitarget.h +20 -5
  244. data/ext/ffi_c/libffi/src/sparc/internal.h +26 -0
  245. data/ext/ffi_c/libffi/src/sparc/v8.S +364 -234
  246. data/ext/ffi_c/libffi/src/sparc/v9.S +340 -207
  247. data/ext/ffi_c/libffi/src/tile/ffi.c +355 -0
  248. data/ext/ffi_c/libffi/src/tile/ffitarget.h +65 -0
  249. data/ext/ffi_c/libffi/src/tile/tile.S +360 -0
  250. data/ext/ffi_c/libffi/src/tramp.c +716 -0
  251. data/ext/ffi_c/libffi/src/types.c +48 -19
  252. data/ext/ffi_c/libffi/src/vax/elfbsd.S +195 -0
  253. data/ext/ffi_c/libffi/src/vax/ffi.c +276 -0
  254. data/ext/ffi_c/libffi/src/vax/ffitarget.h +49 -0
  255. data/ext/ffi_c/libffi/src/wasm32/ffi.c +947 -0
  256. data/ext/ffi_c/libffi/src/wasm32/ffitarget.h +62 -0
  257. data/ext/ffi_c/libffi/src/x86/asmnames.h +30 -0
  258. data/ext/ffi_c/libffi/src/x86/ffi.c +690 -540
  259. data/ext/ffi_c/libffi/src/x86/ffi64.c +450 -126
  260. data/ext/ffi_c/libffi/src/x86/ffitarget.h +86 -42
  261. data/ext/ffi_c/libffi/src/x86/ffiw64.c +361 -0
  262. data/ext/ffi_c/libffi/src/x86/internal.h +43 -0
  263. data/ext/ffi_c/libffi/src/x86/internal64.h +36 -0
  264. data/ext/ffi_c/libffi/src/x86/sysv.S +1199 -381
  265. data/ext/ffi_c/libffi/src/x86/sysv_intel.S +998 -0
  266. data/ext/ffi_c/libffi/src/x86/unix64.S +587 -298
  267. data/ext/ffi_c/libffi/src/x86/win64.S +251 -457
  268. data/ext/ffi_c/libffi/src/x86/win64_intel.S +238 -0
  269. data/ext/ffi_c/libffi/src/xtensa/ffi.c +306 -0
  270. data/ext/ffi_c/libffi/src/xtensa/ffitarget.h +57 -0
  271. data/ext/ffi_c/libffi/src/xtensa/sysv.S +268 -0
  272. data/ext/ffi_c/libffi/stamp-h.in +1 -0
  273. data/ext/ffi_c/libffi/testsuite/Makefile.am +80 -73
  274. data/ext/ffi_c/libffi/testsuite/Makefile.in +251 -117
  275. data/ext/ffi_c/libffi/testsuite/emscripten/build-tests.sh +54 -0
  276. data/ext/ffi_c/libffi/testsuite/emscripten/build.sh +63 -0
  277. data/ext/ffi_c/libffi/testsuite/emscripten/conftest.py +86 -0
  278. data/ext/ffi_c/libffi/testsuite/emscripten/node-tests.sh +48 -0
  279. data/ext/ffi_c/libffi/testsuite/emscripten/test.html +7 -0
  280. data/ext/ffi_c/libffi/testsuite/emscripten/test_libffi.py +51 -0
  281. data/ext/ffi_c/libffi/testsuite/lib/libffi.exp +682 -0
  282. data/ext/ffi_c/libffi/testsuite/lib/target-libpath.exp +22 -2
  283. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/Makefile +28 -0
  284. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/README +78 -0
  285. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/alignof.h +50 -0
  286. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/bhaible.exp +63 -0
  287. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/test-call.c +1746 -0
  288. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/test-callback.c +2885 -0
  289. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/testcases.c +747 -0
  290. data/ext/ffi_c/libffi/testsuite/libffi.call/align_mixed.c +46 -0
  291. data/ext/ffi_c/libffi/testsuite/libffi.call/align_stdcall.c +46 -0
  292. data/ext/ffi_c/libffi/testsuite/libffi.call/bpo_38748.c +41 -0
  293. data/ext/ffi_c/libffi/testsuite/libffi.call/call.exp +28 -10
  294. data/ext/ffi_c/libffi/testsuite/libffi.call/callback.c +99 -0
  295. data/ext/ffi_c/libffi/testsuite/libffi.call/callback2.c +108 -0
  296. data/ext/ffi_c/libffi/testsuite/libffi.call/callback3.c +114 -0
  297. data/ext/ffi_c/libffi/testsuite/libffi.call/callback4.c +119 -0
  298. data/ext/ffi_c/libffi/testsuite/libffi.call/err_bad_typedef.c +4 -3
  299. data/ext/ffi_c/libffi/testsuite/libffi.call/ffitest.h +88 -42
  300. data/ext/ffi_c/libffi/testsuite/libffi.call/float1.c +3 -1
  301. data/ext/ffi_c/libffi/testsuite/libffi.call/float2.c +15 -12
  302. data/ext/ffi_c/libffi/testsuite/libffi.call/float3.c +4 -2
  303. data/ext/ffi_c/libffi/testsuite/libffi.call/float_va.c +110 -0
  304. data/ext/ffi_c/libffi/testsuite/libffi.call/many.c +6 -16
  305. data/ext/ffi_c/libffi/testsuite/libffi.call/many2.c +57 -0
  306. data/ext/ffi_c/libffi/testsuite/libffi.call/many_double.c +70 -0
  307. data/ext/ffi_c/libffi/testsuite/libffi.call/many_mixed.c +78 -0
  308. data/ext/ffi_c/libffi/testsuite/libffi.call/negint.c +0 -1
  309. data/ext/ffi_c/libffi/testsuite/libffi.call/offsets.c +46 -0
  310. data/ext/ffi_c/libffi/testsuite/libffi.call/pr1172638.c +127 -0
  311. data/ext/ffi_c/libffi/testsuite/libffi.call/return_dbl.c +1 -0
  312. data/ext/ffi_c/libffi/testsuite/libffi.call/return_ldl.c +1 -1
  313. data/ext/ffi_c/libffi/testsuite/libffi.call/return_ll1.c +6 -0
  314. data/ext/ffi_c/libffi/testsuite/libffi.call/return_sc.c +1 -1
  315. data/ext/ffi_c/libffi/testsuite/libffi.call/return_sl.c +4 -0
  316. data/ext/ffi_c/libffi/testsuite/libffi.call/return_uc.c +1 -1
  317. data/ext/ffi_c/libffi/testsuite/libffi.call/return_ul.c +4 -0
  318. data/ext/ffi_c/libffi/testsuite/libffi.call/s55.c +60 -0
  319. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen.c +9 -10
  320. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen2.c +49 -0
  321. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen3.c +49 -0
  322. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen4.c +55 -0
  323. data/ext/ffi_c/libffi/testsuite/libffi.call/struct1.c +9 -7
  324. data/ext/ffi_c/libffi/testsuite/libffi.call/struct10.c +57 -0
  325. data/ext/ffi_c/libffi/testsuite/libffi.call/struct2.c +7 -7
  326. data/ext/ffi_c/libffi/testsuite/libffi.call/struct3.c +7 -6
  327. data/ext/ffi_c/libffi/testsuite/libffi.call/struct4.c +9 -8
  328. data/ext/ffi_c/libffi/testsuite/libffi.call/struct5.c +9 -8
  329. data/ext/ffi_c/libffi/testsuite/libffi.call/struct6.c +9 -9
  330. data/ext/ffi_c/libffi/testsuite/libffi.call/struct7.c +9 -9
  331. data/ext/ffi_c/libffi/testsuite/libffi.call/struct8.c +9 -8
  332. data/ext/ffi_c/libffi/testsuite/libffi.call/struct9.c +9 -8
  333. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_2.c +63 -0
  334. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_3.c +65 -0
  335. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_3f.c +65 -0
  336. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_4.c +67 -0
  337. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_4f.c +67 -0
  338. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_big.c +93 -0
  339. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_small.c +61 -0
  340. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_return_2H.c +63 -0
  341. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_return_8H.c +90 -0
  342. data/ext/ffi_c/libffi/testsuite/libffi.call/uninitialized.c +61 -0
  343. data/ext/ffi_c/libffi/testsuite/libffi.call/va_1.c +78 -0
  344. data/ext/ffi_c/libffi/testsuite/libffi.call/va_2.c +220 -0
  345. data/ext/ffi_c/libffi/testsuite/libffi.call/va_3.c +154 -0
  346. data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct1.c +134 -0
  347. data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct2.c +134 -0
  348. data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct3.c +140 -0
  349. data/ext/ffi_c/libffi/testsuite/libffi.closures/closure.exp +67 -0
  350. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/closure_fn0.c +3 -2
  351. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/closure_fn1.c +2 -0
  352. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/closure_fn2.c +2 -0
  353. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/closure_fn3.c +21 -1
  354. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/closure_fn4.c +2 -0
  355. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/closure_fn5.c +2 -0
  356. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/closure_fn6.c +2 -0
  357. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/closure_loc_fn0.c +7 -6
  358. data/ext/ffi_c/libffi/testsuite/{libffi.call/closure_stdcall.c → libffi.closures/closure_simple.c} +13 -16
  359. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_12byte.c +22 -4
  360. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_16byte.c +26 -4
  361. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_18byte.c +28 -4
  362. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_19byte.c +33 -4
  363. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_1_1byte.c +8 -4
  364. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_20byte.c +23 -5
  365. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_20byte1.c +25 -5
  366. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_24byte.c +40 -8
  367. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_2byte.c +17 -4
  368. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_3_1byte.c +23 -4
  369. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_3byte1.c +17 -4
  370. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_3byte2.c +17 -4
  371. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_3float.c +113 -0
  372. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_4_1byte.c +26 -4
  373. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_4byte.c +17 -4
  374. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_5_1_byte.c +33 -5
  375. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_5byte.c +23 -5
  376. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_64byte.c +29 -5
  377. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_6_1_byte.c +32 -5
  378. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_6byte.c +28 -6
  379. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_7_1_byte.c +43 -5
  380. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_7byte.c +29 -5
  381. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_8byte.c +18 -4
  382. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_9byte1.c +18 -5
  383. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_9byte2.c +18 -6
  384. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_double.c +23 -5
  385. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_float.c +23 -5
  386. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_longdouble.c +24 -5
  387. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_longdouble_split.c +44 -31
  388. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_longdouble_split2.c +44 -9
  389. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_pointer.c +23 -5
  390. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_sint16.c +22 -5
  391. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_sint32.c +22 -7
  392. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_sint64.c +23 -5
  393. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_uint16.c +22 -5
  394. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_uint32.c +23 -5
  395. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_align_uint64.c +24 -5
  396. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_dbls_struct.c +7 -5
  397. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_double_va.c +21 -9
  398. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_float.c +4 -0
  399. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_longdouble.c +13 -3
  400. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_longdouble_va.c +34 -11
  401. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_many_mixed_args.c +70 -0
  402. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_many_mixed_float_double.c +55 -0
  403. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_multi_schar.c +5 -1
  404. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_multi_sshort.c +6 -1
  405. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_multi_sshortchar.c +9 -1
  406. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_multi_uchar.c +9 -1
  407. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_multi_ushort.c +6 -2
  408. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_multi_ushortchar.c +9 -1
  409. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_pointer.c +7 -2
  410. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_pointer_stack.c +22 -10
  411. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_schar.c +3 -0
  412. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_sint.c +2 -0
  413. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_sshort.c +3 -0
  414. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_struct_va1.c +125 -0
  415. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_uchar.c +3 -0
  416. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_uint.c +4 -0
  417. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_uint_va.c +49 -0
  418. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_ulong_va.c +49 -0
  419. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_ulonglong.c +8 -5
  420. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_ushort.c +3 -0
  421. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/err_bad_abi.c +2 -3
  422. data/ext/ffi_c/libffi/testsuite/libffi.closures/ffitest.h +1 -0
  423. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/huge_struct.c +57 -56
  424. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct.c +38 -15
  425. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct1.c +9 -9
  426. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct10.c +19 -6
  427. data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct11.c +137 -0
  428. data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct12.c +86 -0
  429. data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct13.c +115 -0
  430. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct2.c +15 -6
  431. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct3.c +15 -6
  432. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct4.c +14 -5
  433. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct5.c +14 -5
  434. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct6.c +17 -6
  435. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct7.c +14 -5
  436. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct8.c +17 -6
  437. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/nested_struct9.c +17 -6
  438. data/ext/ffi_c/libffi/testsuite/libffi.closures/single_entry_structs1.c +86 -0
  439. data/ext/ffi_c/libffi/testsuite/libffi.closures/single_entry_structs2.c +102 -0
  440. data/ext/ffi_c/libffi/testsuite/libffi.closures/single_entry_structs3.c +101 -0
  441. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/stret_large.c +7 -7
  442. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/stret_large2.c +7 -7
  443. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/stret_medium.c +6 -6
  444. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/stret_medium2.c +7 -6
  445. data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/testclosure.c +8 -3
  446. data/ext/ffi_c/libffi/testsuite/{libffi.special → libffi.closures}/unwindtest.cc +4 -10
  447. data/ext/ffi_c/libffi/testsuite/{libffi.special → libffi.closures}/unwindtest_ffi_call.cc +4 -2
  448. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_align_complex.inc +91 -0
  449. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_align_complex_double.c +10 -0
  450. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_align_complex_float.c +10 -0
  451. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_align_complex_longdouble.c +10 -0
  452. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex.inc +42 -0
  453. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_double.c +10 -0
  454. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_float.c +10 -0
  455. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_longdouble.c +10 -0
  456. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_struct.inc +71 -0
  457. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_struct_double.c +10 -0
  458. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_struct_float.c +10 -0
  459. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_struct_longdouble.c +10 -0
  460. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_va.inc +80 -0
  461. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_va_double.c +10 -0
  462. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_va_float.c +16 -0
  463. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_va_longdouble.c +10 -0
  464. data/ext/ffi_c/libffi/testsuite/{libffi.special/special.exp → libffi.complex/complex.exp} +9 -10
  465. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex.inc +51 -0
  466. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_defs_double.inc +7 -0
  467. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_defs_float.inc +7 -0
  468. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_defs_longdouble.inc +7 -0
  469. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_double.c +10 -0
  470. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_float.c +10 -0
  471. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_int.c +86 -0
  472. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_longdouble.c +10 -0
  473. data/ext/ffi_c/libffi/testsuite/libffi.complex/ffitest.h +1 -0
  474. data/ext/ffi_c/libffi/testsuite/libffi.complex/many_complex.inc +78 -0
  475. data/ext/ffi_c/libffi/testsuite/libffi.complex/many_complex_double.c +10 -0
  476. data/ext/ffi_c/libffi/testsuite/libffi.complex/many_complex_float.c +10 -0
  477. data/ext/ffi_c/libffi/testsuite/libffi.complex/many_complex_longdouble.c +10 -0
  478. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex.inc +37 -0
  479. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex1.inc +41 -0
  480. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex1_double.c +10 -0
  481. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex1_float.c +10 -0
  482. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex1_longdouble.c +10 -0
  483. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex2.inc +44 -0
  484. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex2_double.c +10 -0
  485. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex2_float.c +10 -0
  486. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex2_longdouble.c +10 -0
  487. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex_double.c +10 -0
  488. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex_float.c +10 -0
  489. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex_longdouble.c +10 -0
  490. data/ext/ffi_c/libffi/testsuite/libffi.go/aa-direct.c +34 -0
  491. data/ext/ffi_c/libffi/testsuite/libffi.go/closure1.c +28 -0
  492. data/ext/ffi_c/libffi/testsuite/libffi.go/ffitest.h +1 -0
  493. data/ext/ffi_c/libffi/testsuite/libffi.go/go.exp +36 -0
  494. data/ext/ffi_c/libffi/testsuite/libffi.go/static-chain.h +19 -0
  495. data/ext/ffi_c/libffi.bsd.mk +14 -8
  496. data/ext/ffi_c/libffi.darwin.mk +56 -26
  497. data/ext/ffi_c/libffi.gnu.mk +9 -6
  498. data/ext/ffi_c/libffi.mk +13 -8
  499. data/ext/ffi_c/libffi.vc.mk +26 -0
  500. data/ext/ffi_c/libffi.vc64.mk +26 -0
  501. data/ext/ffi_c/rbffi.h +34 -6
  502. data/ext/ffi_c/{endian.h → rbffi_endian.h} +21 -2
  503. data/ffi.gemspec +42 -0
  504. data/lib/ffi/abstract_memory.rb +44 -0
  505. data/lib/ffi/autopointer.rb +111 -52
  506. data/lib/ffi/compat.rb +43 -0
  507. data/lib/ffi/data_converter.rb +67 -0
  508. data/lib/ffi/dynamic_library.rb +118 -0
  509. data/lib/ffi/enum.rb +203 -22
  510. data/lib/ffi/errno.rb +27 -12
  511. data/lib/ffi/ffi.rb +88 -11
  512. data/lib/ffi/function.rb +71 -0
  513. data/lib/ffi/io.rb +35 -14
  514. data/lib/ffi/library.rb +382 -96
  515. data/lib/ffi/library_path.rb +109 -0
  516. data/lib/ffi/managedstruct.rb +64 -35
  517. data/lib/ffi/memorypointer.rb +1 -33
  518. data/lib/ffi/platform/aarch64-darwin/types.conf +130 -0
  519. data/lib/ffi/platform/aarch64-freebsd/types.conf +128 -0
  520. data/lib/ffi/platform/aarch64-freebsd12/types.conf +181 -0
  521. data/lib/ffi/platform/aarch64-linux/types.conf +175 -0
  522. data/lib/ffi/platform/aarch64-openbsd/types.conf +134 -0
  523. data/lib/ffi/platform/aarch64-windows/types.conf +52 -0
  524. data/lib/ffi/platform/arm-freebsd/types.conf +152 -0
  525. data/lib/ffi/platform/arm-freebsd12/types.conf +152 -0
  526. data/lib/ffi/platform/arm-linux/types.conf +132 -0
  527. data/lib/ffi/platform/hppa1.1-linux/types.conf +178 -0
  528. data/lib/ffi/platform/hppa2.0-linux/types.conf +178 -0
  529. data/lib/ffi/platform/i386-cygwin/types.conf +3 -0
  530. data/lib/ffi/platform/i386-darwin/types.conf +100 -0
  531. data/lib/ffi/platform/i386-freebsd/types.conf +152 -0
  532. data/lib/ffi/platform/i386-freebsd12/types.conf +152 -0
  533. data/lib/ffi/platform/i386-gnu/types.conf +107 -0
  534. data/lib/ffi/platform/i386-linux/types.conf +103 -0
  535. data/lib/ffi/platform/i386-netbsd/types.conf +126 -0
  536. data/lib/ffi/platform/i386-openbsd/types.conf +128 -0
  537. data/lib/ffi/platform/i386-solaris/types.conf +122 -0
  538. data/lib/ffi/platform/i386-windows/types.conf +52 -0
  539. data/lib/ffi/platform/ia64-linux/types.conf +104 -0
  540. data/lib/ffi/platform/loongarch64-linux/types.conf +141 -0
  541. data/lib/ffi/platform/mips-linux/types.conf +102 -0
  542. data/lib/ffi/platform/mips64-linux/types.conf +104 -0
  543. data/lib/ffi/platform/mips64el-linux/types.conf +104 -0
  544. data/lib/ffi/platform/mipsel-linux/types.conf +102 -0
  545. data/lib/ffi/platform/mipsisa32r6-linux/types.conf +102 -0
  546. data/lib/ffi/platform/mipsisa32r6el-linux/types.conf +102 -0
  547. data/lib/ffi/platform/mipsisa64r6-linux/types.conf +104 -0
  548. data/lib/ffi/platform/mipsisa64r6el-linux/types.conf +104 -0
  549. data/lib/ffi/platform/powerpc-aix/types.conf +180 -0
  550. data/lib/ffi/platform/powerpc-darwin/types.conf +100 -0
  551. data/lib/ffi/platform/powerpc-linux/types.conf +130 -0
  552. data/lib/ffi/platform/powerpc-openbsd/types.conf +156 -0
  553. data/lib/ffi/platform/powerpc64-linux/types.conf +104 -0
  554. data/lib/ffi/platform/powerpc64le-linux/types.conf +100 -0
  555. data/lib/ffi/platform/riscv64-linux/types.conf +104 -0
  556. data/lib/ffi/platform/s390-linux/types.conf +102 -0
  557. data/lib/ffi/platform/s390x-linux/types.conf +102 -0
  558. data/lib/ffi/platform/sparc-linux/types.conf +102 -0
  559. data/lib/ffi/platform/sparc-solaris/types.conf +128 -0
  560. data/lib/ffi/platform/sparcv9-linux/types.conf +102 -0
  561. data/lib/ffi/platform/sparcv9-openbsd/types.conf +156 -0
  562. data/lib/ffi/platform/sparcv9-solaris/types.conf +128 -0
  563. data/lib/ffi/platform/sw_64-linux/types.conf +141 -0
  564. data/lib/ffi/platform/x86_64-cygwin/types.conf +3 -0
  565. data/lib/ffi/platform/x86_64-darwin/types.conf +130 -0
  566. data/lib/ffi/platform/x86_64-dragonflybsd/types.conf +130 -0
  567. data/lib/ffi/platform/x86_64-freebsd/types.conf +128 -0
  568. data/lib/ffi/platform/x86_64-freebsd12/types.conf +158 -0
  569. data/lib/ffi/platform/x86_64-haiku/types.conf +117 -0
  570. data/lib/ffi/platform/x86_64-linux/types.conf +132 -0
  571. data/lib/ffi/platform/x86_64-msys/types.conf +119 -0
  572. data/lib/ffi/platform/x86_64-netbsd/types.conf +128 -0
  573. data/lib/ffi/platform/x86_64-openbsd/types.conf +134 -0
  574. data/lib/ffi/platform/x86_64-solaris/types.conf +122 -0
  575. data/lib/ffi/platform/x86_64-windows/types.conf +52 -0
  576. data/lib/ffi/platform.rb +110 -34
  577. data/lib/ffi/pointer.rb +117 -90
  578. data/lib/ffi/struct.rb +101 -70
  579. data/lib/ffi/struct_by_reference.rb +72 -0
  580. data/lib/ffi/struct_layout.rb +96 -0
  581. data/lib/ffi/struct_layout_builder.rb +90 -21
  582. data/lib/ffi/tools/const_generator.rb +86 -31
  583. data/lib/ffi/tools/generator.rb +49 -2
  584. data/lib/ffi/tools/generator_task.rb +13 -16
  585. data/lib/ffi/tools/struct_generator.rb +6 -5
  586. data/lib/ffi/tools/types_generator.rb +25 -11
  587. data/lib/ffi/types.rb +105 -36
  588. data/lib/ffi/union.rb +23 -12
  589. data/lib/ffi/variadic.rb +44 -29
  590. data/lib/ffi/version.rb +3 -0
  591. data/lib/ffi.rb +25 -9
  592. data/rakelib/ffi_gem_helper.rb +65 -0
  593. data/samples/getlogin.rb +8 -0
  594. data/samples/getpid.rb +8 -0
  595. data/samples/gettimeofday.rb +18 -0
  596. data/samples/hello.rb +8 -0
  597. data/samples/hello_ractor.rb +11 -0
  598. data/samples/inotify.rb +60 -0
  599. data/samples/pty.rb +75 -0
  600. data/samples/qsort.rb +20 -0
  601. data/samples/qsort_ractor.rb +28 -0
  602. data/sig/ffi/abstract_memory.rbs +165 -0
  603. data/sig/ffi/auto_pointer.rbs +26 -0
  604. data/sig/ffi/buffer.rbs +18 -0
  605. data/sig/ffi/data_converter.rbs +10 -0
  606. data/sig/ffi/dynamic_library.rbs +9 -0
  607. data/sig/ffi/enum.rbs +38 -0
  608. data/sig/ffi/function.rbs +39 -0
  609. data/sig/ffi/library.rbs +42 -0
  610. data/sig/ffi/native_type.rbs +86 -0
  611. data/sig/ffi/pointer.rbs +42 -0
  612. data/sig/ffi/struct.rbs +76 -0
  613. data/sig/ffi/struct_by_reference.rbs +11 -0
  614. data/sig/ffi/struct_by_value.rbs +7 -0
  615. data/sig/ffi/struct_layout.rbs +9 -0
  616. data/sig/ffi/struct_layout_builder.rbs +5 -0
  617. data/sig/ffi/type.rbs +39 -0
  618. data/sig/ffi.rbs +26 -0
  619. data.tar.gz.sig +0 -0
  620. metadata +547 -248
  621. metadata.gz.sig +0 -0
  622. data/History.txt +0 -109
  623. data/README.rdoc +0 -70
  624. data/ext/ffi_c/DataConverter.c +0 -62
  625. data/ext/ffi_c/StructByReference.c +0 -150
  626. data/ext/ffi_c/StructByReference.h +0 -50
  627. data/ext/ffi_c/libffi/ChangeLog.libffi +0 -658
  628. data/ext/ffi_c/libffi/ChangeLog.libgcj +0 -40
  629. data/ext/ffi_c/libffi/ChangeLog.v1 +0 -764
  630. data/ext/ffi_c/libffi/README +0 -306
  631. data/ext/ffi_c/libffi/aclocal.m4 +0 -8998
  632. data/ext/ffi_c/libffi/depcomp +0 -584
  633. data/ext/ffi_c/libffi/doc/libffi.info +0 -533
  634. data/ext/ffi_c/libffi/doc/stamp-vti +0 -4
  635. data/ext/ffi_c/libffi/m4/libtool.m4 +0 -7360
  636. data/ext/ffi_c/libffi/m4/ltoptions.m4 +0 -368
  637. data/ext/ffi_c/libffi/m4/ltsugar.m4 +0 -123
  638. data/ext/ffi_c/libffi/m4/ltversion.m4 +0 -23
  639. data/ext/ffi_c/libffi/m4/lt~obsolete.m4 +0 -92
  640. data/ext/ffi_c/libffi/mdate-sh +0 -201
  641. data/ext/ffi_c/libffi/src/x86/darwin.S +0 -444
  642. data/ext/ffi_c/libffi/src/x86/darwin64.S +0 -416
  643. data/ext/ffi_c/libffi/src/x86/freebsd.S +0 -458
  644. data/ext/ffi_c/libffi/src/x86/win32.S +0 -877
  645. data/ext/ffi_c/libffi/testsuite/lib/libffi-dg.exp +0 -300
  646. data/ext/ffi_c/libffi/testsuite/libffi.call/many_win32.c +0 -63
  647. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen_win32.c +0 -44
  648. data/ext/ffi_c/libffi/testsuite/libffi.special/ffitestcxx.h +0 -96
  649. data/ext/ffi_c/libffi/texinfo.tex +0 -7210
  650. data/gen/Rakefile +0 -14
  651. data/spec/ffi/async_callback_spec.rb +0 -23
  652. data/spec/ffi/bool_spec.rb +0 -24
  653. data/spec/ffi/buffer_spec.rb +0 -202
  654. data/spec/ffi/callback_spec.rb +0 -653
  655. data/spec/ffi/custom_param_type.rb +0 -31
  656. data/spec/ffi/custom_type_spec.rb +0 -73
  657. data/spec/ffi/enum_spec.rb +0 -183
  658. data/spec/ffi/errno_spec.rb +0 -13
  659. data/spec/ffi/ffi_spec.rb +0 -24
  660. data/spec/ffi/function_spec.rb +0 -73
  661. data/spec/ffi/library_spec.rb +0 -174
  662. data/spec/ffi/managed_struct_spec.rb +0 -56
  663. data/spec/ffi/number_spec.rb +0 -231
  664. data/spec/ffi/pointer_spec.rb +0 -210
  665. data/spec/ffi/rbx/attach_function_spec.rb +0 -28
  666. data/spec/ffi/rbx/memory_pointer_spec.rb +0 -109
  667. data/spec/ffi/rbx/spec_helper.rb +0 -1
  668. data/spec/ffi/rbx/struct_spec.rb +0 -13
  669. data/spec/ffi/spec_helper.rb +0 -21
  670. data/spec/ffi/string_spec.rb +0 -103
  671. data/spec/ffi/strptr_spec.rb +0 -36
  672. data/spec/ffi/struct_callback_spec.rb +0 -64
  673. data/spec/ffi/struct_initialize_spec.rb +0 -30
  674. data/spec/ffi/struct_packed_spec.rb +0 -46
  675. data/spec/ffi/struct_spec.rb +0 -638
  676. data/spec/ffi/typedef_spec.rb +0 -62
  677. data/spec/ffi/union_spec.rb +0 -60
  678. data/spec/ffi/variadic_spec.rb +0 -84
  679. data/spec/spec.opts +0 -4
  680. data/tasks/ann.rake +0 -80
  681. data/tasks/extension.rake +0 -25
  682. data/tasks/gem.rake +0 -200
  683. data/tasks/git.rake +0 -41
  684. data/tasks/notes.rake +0 -27
  685. data/tasks/post_load.rake +0 -34
  686. data/tasks/rdoc.rake +0 -50
  687. data/tasks/rubyforge.rake +0 -55
  688. data/tasks/setup.rb +0 -301
  689. data/tasks/spec.rake +0 -54
  690. data/tasks/svn.rake +0 -47
  691. data/tasks/test.rake +0 -40
  692. /data/ext/ffi_c/libffi/testsuite/libffi.call/{pyobjc-tc.c → pyobjc_tc.c} +0 -0
  693. /data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/cls_double.c +0 -0
  694. /data/ext/ffi_c/libffi/testsuite/{libffi.call → libffi.closures}/problem1.c +0 -0
@@ -1,6 +1,8 @@
1
1
  /* -----------------------------------------------------------------------
2
- closures.c - Copyright (c) 2007, 2009 Red Hat, Inc.
3
- Copyright (C) 2007, 2009 Free Software Foundation, Inc
2
+ closures.c - Copyright (c) 2019, 2022 Anthony Green
3
+ Copyright (c) 2007, 2009, 2010 Red Hat, Inc.
4
+ Copyright (C) 2007, 2009, 2010 Free Software Foundation, Inc
5
+ Copyright (c) 2011 Plausible Labs Cooperative, Inc.
4
6
 
5
7
  Code to allocate and deallocate memory for closures.
6
8
 
@@ -25,15 +27,104 @@
25
27
  DEALINGS IN THE SOFTWARE.
26
28
  ----------------------------------------------------------------------- */
27
29
 
28
- #if defined __linux__ && !defined _GNU_SOURCE
30
+ #if (defined __linux__ || defined __CYGWIN__) && !defined _GNU_SOURCE
29
31
  #define _GNU_SOURCE 1
30
32
  #endif
31
33
 
34
+ #ifndef __EMSCRIPTEN__
35
+
36
+ #include <fficonfig.h>
32
37
  #include <ffi.h>
33
38
  #include <ffi_common.h>
39
+ #include <tramp.h>
40
+
41
+ #ifdef __NetBSD__
42
+ #include <sys/param.h>
43
+ #endif
44
+
45
+ #if __NetBSD_Version__ - 0 >= 799007200
46
+ /* NetBSD with PROT_MPROTECT */
47
+ #include <sys/mman.h>
48
+
49
+ #include <stddef.h>
50
+ #include <unistd.h>
51
+ #ifdef HAVE_SYS_MEMFD_H
52
+ #include <sys/memfd.h>
53
+ #endif
54
+
55
+ static const size_t overhead =
56
+ (sizeof(max_align_t) > sizeof(void *) + sizeof(size_t)) ?
57
+ sizeof(max_align_t)
58
+ : sizeof(void *) + sizeof(size_t);
59
+
60
+ #define ADD_TO_POINTER(p, d) ((void *)((uintptr_t)(p) + (d)))
61
+
62
+ void *
63
+ ffi_closure_alloc (size_t size, void **code)
64
+ {
65
+ static size_t page_size;
66
+ size_t rounded_size;
67
+ void *codeseg, *dataseg;
68
+ int prot;
69
+
70
+ /* Expect that PAX mprotect is active and a separate code mapping is necessary. */
71
+ if (!code)
72
+ return NULL;
73
+
74
+ /* Obtain system page size. */
75
+ if (!page_size)
76
+ page_size = sysconf(_SC_PAGESIZE);
77
+
78
+ /* Round allocation size up to the next page, keeping in mind the size field and pointer to code map. */
79
+ rounded_size = (size + overhead + page_size - 1) & ~(page_size - 1);
80
+
81
+ /* Primary mapping is RW, but request permission to switch to PROT_EXEC later. */
82
+ prot = PROT_READ | PROT_WRITE | PROT_MPROTECT(PROT_EXEC);
83
+ dataseg = mmap(NULL, rounded_size, prot, MAP_ANON | MAP_PRIVATE, -1, 0);
84
+ if (dataseg == MAP_FAILED)
85
+ return NULL;
86
+
87
+ /* Create secondary mapping and switch it to RX. */
88
+ codeseg = mremap(dataseg, rounded_size, NULL, rounded_size, MAP_REMAPDUP);
89
+ if (codeseg == MAP_FAILED) {
90
+ munmap(dataseg, rounded_size);
91
+ return NULL;
92
+ }
93
+ if (mprotect(codeseg, rounded_size, PROT_READ | PROT_EXEC) == -1) {
94
+ munmap(codeseg, rounded_size);
95
+ munmap(dataseg, rounded_size);
96
+ return NULL;
97
+ }
98
+
99
+ /* Remember allocation size and location of the secondary mapping for ffi_closure_free. */
100
+ memcpy(dataseg, &rounded_size, sizeof(rounded_size));
101
+ memcpy(ADD_TO_POINTER(dataseg, sizeof(size_t)), &codeseg, sizeof(void *));
102
+ *code = ADD_TO_POINTER(codeseg, overhead);
103
+ return ADD_TO_POINTER(dataseg, overhead);
104
+ }
105
+
106
+ void
107
+ ffi_closure_free (void *ptr)
108
+ {
109
+ void *codeseg, *dataseg;
110
+ size_t rounded_size;
111
+
112
+ dataseg = ADD_TO_POINTER(ptr, -overhead);
113
+ memcpy(&rounded_size, dataseg, sizeof(rounded_size));
114
+ memcpy(&codeseg, ADD_TO_POINTER(dataseg, sizeof(size_t)), sizeof(void *));
115
+ munmap(dataseg, rounded_size);
116
+ munmap(codeseg, rounded_size);
117
+ }
118
+
119
+ int
120
+ ffi_tramp_is_present (__attribute__((unused)) void *ptr)
121
+ {
122
+ return 0;
123
+ }
124
+ #else /* !NetBSD with PROT_MPROTECT */
34
125
 
35
- #ifndef FFI_MMAP_EXEC_WRIT
36
- # if __gnu_linux__
126
+ #if !FFI_MMAP_EXEC_WRIT && !FFI_EXEC_TRAMPOLINE_TABLE
127
+ # if __linux__ && !defined(__ANDROID__)
37
128
  /* This macro indicates it may be forbidden to map anonymous memory
38
129
  with both write and execute permission. Code compiled when this
39
130
  option is defined will attempt to map such pages once, but if it
@@ -44,26 +135,261 @@
44
135
  # define FFI_MMAP_EXEC_WRIT 1
45
136
  # define HAVE_MNTENT 1
46
137
  # endif
47
- # if defined(X86_WIN32) || defined(X86_WIN64)
48
- /* Windows systems may have Data Execution Protection (DEP) enabled,
138
+ # if defined(__CYGWIN__) || defined(_WIN32) || defined(__OS2__)
139
+ /* Windows systems may have Data Execution Protection (DEP) enabled,
49
140
  which requires the use of VirtualMalloc/VirtualFree to alloc/free
50
141
  executable memory. */
51
142
  # define FFI_MMAP_EXEC_WRIT 1
52
143
  # endif
53
144
  #endif
54
145
 
55
- #if FFI_MMAP_EXEC_WRIT && !defined FFI_MMAP_EXEC_SELINUX
56
- # ifdef __linux__
146
+ #if FFI_MMAP_EXEC_WRIT && defined(__linux__) && !defined(__ANDROID__)
147
+ # if !defined FFI_MMAP_EXEC_SELINUX
57
148
  /* When defined to 1 check for SELinux and if SELinux is active,
58
149
  don't attempt PROT_EXEC|PROT_WRITE mapping at all, as that
59
150
  might cause audit messages. */
60
151
  # define FFI_MMAP_EXEC_SELINUX 1
61
- # endif
62
- #endif
152
+ # endif /* !defined FFI_MMAP_EXEC_SELINUX */
153
+ # if !defined FFI_MMAP_PAX
154
+ /* Also check for PaX MPROTECT */
155
+ # define FFI_MMAP_PAX 1
156
+ # endif /* !defined FFI_MMAP_PAX */
157
+ #endif /* FFI_MMAP_EXEC_WRIT && defined(__linux__) && !defined(__ANDROID__) */
63
158
 
64
159
  #if FFI_CLOSURES
65
160
 
66
- # if FFI_MMAP_EXEC_WRIT
161
+ #if FFI_EXEC_TRAMPOLINE_TABLE
162
+
163
+ #ifdef __MACH__
164
+
165
+ #include <mach/mach.h>
166
+ #include <pthread.h>
167
+ #ifdef HAVE_PTRAUTH
168
+ #include <ptrauth.h>
169
+ #endif
170
+ #include <stdio.h>
171
+ #include <stdlib.h>
172
+
173
+ extern void *ffi_closure_trampoline_table_page;
174
+
175
+ typedef struct ffi_trampoline_table ffi_trampoline_table;
176
+ typedef struct ffi_trampoline_table_entry ffi_trampoline_table_entry;
177
+
178
+ struct ffi_trampoline_table
179
+ {
180
+ /* contiguous writable and executable pages */
181
+ vm_address_t config_page;
182
+
183
+ /* free list tracking */
184
+ uint16_t free_count;
185
+ ffi_trampoline_table_entry *free_list;
186
+ ffi_trampoline_table_entry *free_list_pool;
187
+
188
+ ffi_trampoline_table *prev;
189
+ ffi_trampoline_table *next;
190
+ };
191
+
192
+ struct ffi_trampoline_table_entry
193
+ {
194
+ void *(*trampoline) (void);
195
+ ffi_trampoline_table_entry *next;
196
+ };
197
+
198
+ /* Total number of trampolines that fit in one trampoline table */
199
+ #define FFI_TRAMPOLINE_COUNT (PAGE_MAX_SIZE / FFI_TRAMPOLINE_SIZE)
200
+
201
+ static pthread_mutex_t ffi_trampoline_lock = PTHREAD_MUTEX_INITIALIZER;
202
+ static ffi_trampoline_table *ffi_trampoline_tables = NULL;
203
+
204
+ static ffi_trampoline_table *
205
+ ffi_trampoline_table_alloc (void)
206
+ {
207
+ ffi_trampoline_table *table;
208
+ vm_address_t config_page;
209
+ vm_address_t trampoline_page;
210
+ vm_address_t trampoline_page_template;
211
+ vm_prot_t cur_prot;
212
+ vm_prot_t max_prot;
213
+ kern_return_t kt;
214
+ uint16_t i;
215
+
216
+ /* Allocate two pages -- a config page and a placeholder page */
217
+ config_page = 0x0;
218
+ kt = vm_allocate (mach_task_self (), &config_page, PAGE_MAX_SIZE * 2,
219
+ VM_FLAGS_ANYWHERE);
220
+ if (kt != KERN_SUCCESS)
221
+ return NULL;
222
+
223
+ /* Remap the trampoline table on top of the placeholder page */
224
+ trampoline_page = config_page + PAGE_MAX_SIZE;
225
+
226
+ #ifdef HAVE_PTRAUTH
227
+ trampoline_page_template = (vm_address_t)(uintptr_t)ptrauth_auth_data((void *)&ffi_closure_trampoline_table_page, ptrauth_key_function_pointer, 0);
228
+ #else
229
+ trampoline_page_template = (vm_address_t)&ffi_closure_trampoline_table_page;
230
+ #endif
231
+
232
+ #ifdef __arm__
233
+ /* ffi_closure_trampoline_table_page can be thumb-biased on some ARM archs */
234
+ trampoline_page_template &= ~1UL;
235
+ #endif
236
+ kt = vm_remap (mach_task_self (), &trampoline_page, PAGE_MAX_SIZE, 0x0,
237
+ VM_FLAGS_OVERWRITE, mach_task_self (), trampoline_page_template,
238
+ FALSE, &cur_prot, &max_prot, VM_INHERIT_SHARE);
239
+ if (kt != KERN_SUCCESS)
240
+ {
241
+ vm_deallocate (mach_task_self (), config_page, PAGE_MAX_SIZE * 2);
242
+ return NULL;
243
+ }
244
+
245
+ if (!(cur_prot & VM_PROT_EXECUTE))
246
+ {
247
+ /* If VM_PROT_EXECUTE isn't set on the remapped trampoline page, set it */
248
+ kt = vm_protect (mach_task_self (), trampoline_page, PAGE_MAX_SIZE,
249
+ FALSE, cur_prot | VM_PROT_EXECUTE);
250
+ if (kt != KERN_SUCCESS)
251
+ {
252
+ vm_deallocate (mach_task_self (), config_page, PAGE_MAX_SIZE * 2);
253
+ return NULL;
254
+ }
255
+ }
256
+
257
+ /* We have valid trampoline and config pages */
258
+ table = calloc (1, sizeof (ffi_trampoline_table));
259
+ table->free_count = FFI_TRAMPOLINE_COUNT;
260
+ table->config_page = config_page;
261
+
262
+ /* Create and initialize the free list */
263
+ table->free_list_pool =
264
+ calloc (FFI_TRAMPOLINE_COUNT, sizeof (ffi_trampoline_table_entry));
265
+
266
+ for (i = 0; i < table->free_count; i++)
267
+ {
268
+ ffi_trampoline_table_entry *entry = &table->free_list_pool[i];
269
+ entry->trampoline =
270
+ (void *) (trampoline_page + (i * FFI_TRAMPOLINE_SIZE));
271
+ #ifdef HAVE_PTRAUTH
272
+ entry->trampoline = ptrauth_sign_unauthenticated(entry->trampoline, ptrauth_key_function_pointer, 0);
273
+ #endif
274
+
275
+ if (i < table->free_count - 1)
276
+ entry->next = &table->free_list_pool[i + 1];
277
+ }
278
+
279
+ table->free_list = table->free_list_pool;
280
+
281
+ return table;
282
+ }
283
+
284
+ static void
285
+ ffi_trampoline_table_free (ffi_trampoline_table *table)
286
+ {
287
+ /* Remove from the list */
288
+ if (table->prev != NULL)
289
+ table->prev->next = table->next;
290
+
291
+ if (table->next != NULL)
292
+ table->next->prev = table->prev;
293
+
294
+ /* Deallocate pages */
295
+ vm_deallocate (mach_task_self (), table->config_page, PAGE_MAX_SIZE * 2);
296
+
297
+ /* Deallocate free list */
298
+ free (table->free_list_pool);
299
+ free (table);
300
+ }
301
+
302
+ void *
303
+ ffi_closure_alloc (size_t size, void **code)
304
+ {
305
+ /* Create the closure */
306
+ ffi_closure *closure = malloc (size);
307
+ if (closure == NULL)
308
+ return NULL;
309
+
310
+ pthread_mutex_lock (&ffi_trampoline_lock);
311
+
312
+ /* Check for an active trampoline table with available entries. */
313
+ ffi_trampoline_table *table = ffi_trampoline_tables;
314
+ if (table == NULL || table->free_list == NULL)
315
+ {
316
+ table = ffi_trampoline_table_alloc ();
317
+ if (table == NULL)
318
+ {
319
+ pthread_mutex_unlock (&ffi_trampoline_lock);
320
+ free (closure);
321
+ return NULL;
322
+ }
323
+
324
+ /* Insert the new table at the top of the list */
325
+ table->next = ffi_trampoline_tables;
326
+ if (table->next != NULL)
327
+ table->next->prev = table;
328
+
329
+ ffi_trampoline_tables = table;
330
+ }
331
+
332
+ /* Claim the free entry */
333
+ ffi_trampoline_table_entry *entry = ffi_trampoline_tables->free_list;
334
+ ffi_trampoline_tables->free_list = entry->next;
335
+ ffi_trampoline_tables->free_count--;
336
+ entry->next = NULL;
337
+
338
+ pthread_mutex_unlock (&ffi_trampoline_lock);
339
+
340
+ /* Initialize the return values */
341
+ *code = entry->trampoline;
342
+ closure->trampoline_table = table;
343
+ closure->trampoline_table_entry = entry;
344
+
345
+ return closure;
346
+ }
347
+
348
+ void
349
+ ffi_closure_free (void *ptr)
350
+ {
351
+ ffi_closure *closure = ptr;
352
+
353
+ pthread_mutex_lock (&ffi_trampoline_lock);
354
+
355
+ /* Fetch the table and entry references */
356
+ ffi_trampoline_table *table = closure->trampoline_table;
357
+ ffi_trampoline_table_entry *entry = closure->trampoline_table_entry;
358
+
359
+ /* Return the entry to the free list */
360
+ entry->next = table->free_list;
361
+ table->free_list = entry;
362
+ table->free_count++;
363
+
364
+ /* If all trampolines within this table are free, and at least one other table exists, deallocate
365
+ * the table */
366
+ if (table->free_count == FFI_TRAMPOLINE_COUNT
367
+ && ffi_trampoline_tables != table)
368
+ {
369
+ ffi_trampoline_table_free (table);
370
+ }
371
+ else if (ffi_trampoline_tables != table)
372
+ {
373
+ /* Otherwise, bump this table to the top of the list */
374
+ table->prev = NULL;
375
+ table->next = ffi_trampoline_tables;
376
+ if (ffi_trampoline_tables != NULL)
377
+ ffi_trampoline_tables->prev = table;
378
+
379
+ ffi_trampoline_tables = table;
380
+ }
381
+
382
+ pthread_mutex_unlock (&ffi_trampoline_lock);
383
+
384
+ /* Free the closure */
385
+ free (closure);
386
+ }
387
+
388
+ #endif
389
+
390
+ // Per-target implementation; It's unclear what can reasonable be shared between two OS/architecture implementations.
391
+
392
+ #elif FFI_MMAP_EXEC_WRIT /* !FFI_EXEC_TRAMPOLINE_TABLE */
67
393
 
68
394
  #define USE_LOCKS 1
69
395
  #define USE_DL_PREFIX 1
@@ -89,14 +415,6 @@
89
415
  /* Don't allocate more than a page unless needed. */
90
416
  #define DEFAULT_GRANULARITY ((size_t)malloc_getpagesize)
91
417
 
92
- #if FFI_CLOSURE_TEST
93
- /* Don't release single pages, to avoid a worst-case scenario of
94
- continuously allocating and releasing single pages, but release
95
- pairs of pages, which should do just as well given that allocations
96
- are likely to be small. */
97
- #define DEFAULT_TRIM_THRESHOLD ((size_t)malloc_getpagesize)
98
- #endif
99
-
100
418
  #include <sys/types.h>
101
419
  #include <sys/stat.h>
102
420
  #include <fcntl.h>
@@ -106,7 +424,7 @@
106
424
  #endif
107
425
  #include <string.h>
108
426
  #include <stdio.h>
109
- #if !defined(X86_WIN32) && !defined(X86_WIN64)
427
+ #if !defined(_WIN32)
110
428
  #ifdef HAVE_MNTENT
111
429
  #include <mntent.h>
112
430
  #endif /* HAVE_MNTENT */
@@ -146,7 +464,7 @@ selinux_enabled_check (void)
146
464
  p = strchr (p + 1, ' ');
147
465
  if (p == NULL)
148
466
  break;
149
- if (strncmp (p + 1, "selinuxfs ", 10) != 0)
467
+ if (strncmp (p + 1, "selinuxfs ", 10) == 0)
150
468
  {
151
469
  free (buf);
152
470
  fclose (f);
@@ -167,7 +485,51 @@ selinux_enabled_check (void)
167
485
 
168
486
  #endif /* !FFI_MMAP_EXEC_SELINUX */
169
487
 
170
- #elif defined (__CYGWIN__)
488
+ /* On PaX enable kernels that have MPROTECT enabled we can't use PROT_EXEC. */
489
+ #if defined FFI_MMAP_PAX
490
+ #include <stdlib.h>
491
+
492
+ enum {
493
+ PAX_MPROTECT = (1 << 0),
494
+ PAX_EMUTRAMP = (1 << 1),
495
+ };
496
+ static int cached_pax_flags = -1;
497
+
498
+ static int
499
+ pax_flags_check (void)
500
+ {
501
+ char *buf = NULL;
502
+ size_t len = 0;
503
+ FILE *f;
504
+ int ret;
505
+ f = fopen ("/proc/self/status", "r");
506
+ if (f == NULL)
507
+ return 0;
508
+ ret = 0;
509
+
510
+ while (getline (&buf, &len, f) != -1)
511
+ if (!strncmp (buf, "PaX:", 4))
512
+ {
513
+ if (NULL != strchr (buf + 4, 'M'))
514
+ ret |= PAX_MPROTECT;
515
+ if (NULL != strchr (buf + 4, 'E'))
516
+ ret |= PAX_EMUTRAMP;
517
+ break;
518
+ }
519
+ free (buf);
520
+ fclose (f);
521
+ return ret;
522
+ }
523
+
524
+ #define get_pax_flags() (cached_pax_flags >= 0 ? cached_pax_flags \
525
+ : (cached_pax_flags = pax_flags_check ()))
526
+ #define has_pax_flags(flags) ((flags) == ((flags) & get_pax_flags ()))
527
+ #define is_mprotect_enabled() (has_pax_flags (PAX_MPROTECT))
528
+ #define is_emutramp_enabled() (has_pax_flags (PAX_EMUTRAMP))
529
+
530
+ #endif /* defined FFI_MMAP_PAX */
531
+
532
+ #elif defined (__CYGWIN__) || defined(__INTERIX)
171
533
 
172
534
  #include <sys/mman.h>
173
535
 
@@ -176,6 +538,11 @@ selinux_enabled_check (void)
176
538
 
177
539
  #endif /* !defined(X86_WIN32) && !defined(X86_WIN64) */
178
540
 
541
+ #if !defined FFI_MMAP_PAX
542
+ # define is_mprotect_enabled() 0
543
+ # define is_emutramp_enabled() 0
544
+ #endif /* !defined FFI_MMAP_PAX */
545
+
179
546
  /* Declare all functions defined in dlmalloc.c as static. */
180
547
  static void *dlmalloc(size_t);
181
548
  static void dlfree(void*);
@@ -193,11 +560,11 @@ static int dlmalloc_trim(size_t) MAYBE_UNUSED;
193
560
  static size_t dlmalloc_usable_size(void*) MAYBE_UNUSED;
194
561
  static void dlmalloc_stats(void) MAYBE_UNUSED;
195
562
 
196
- #if !(defined(X86_WIN32) || defined(X86_WIN64)) || defined (__CYGWIN__)
563
+ #if !(defined(_WIN32) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX)
197
564
  /* Use these for mmap and munmap within dlmalloc.c. */
198
565
  static void *dlmmap(void *, size_t, int, int, int, off_t);
199
566
  static int dlmunmap(void *, size_t);
200
- #endif /* !(defined(X86_WIN32) || defined(X86_WIN64)) || defined (__CYGWIN__) */
567
+ #endif /* !(defined(_WIN32) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX) */
201
568
 
202
569
  #define mmap dlmmap
203
570
  #define munmap dlmunmap
@@ -207,9 +574,7 @@ static int dlmunmap(void *, size_t);
207
574
  #undef mmap
208
575
  #undef munmap
209
576
 
210
- #if !(defined(X86_WIN32) || defined(X86_WIN64)) || defined (__CYGWIN__)
211
-
212
- #if FFI_MMAP_EXEC_SELINUX
577
+ #if !(defined(_WIN32) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX)
213
578
 
214
579
  /* A mutex used to synchronize access to *exec* variables in this file. */
215
580
  static pthread_mutex_t open_temp_exec_file_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -221,11 +586,28 @@ static int execfd = -1;
221
586
  /* The amount of space already allocated from the temporary file. */
222
587
  static size_t execsize = 0;
223
588
 
589
+ #ifdef HAVE_MEMFD_CREATE
224
590
  /* Open a temporary file name, and immediately unlink it. */
225
591
  static int
226
- open_temp_exec_file_name (char *name)
592
+ open_temp_exec_file_memfd (const char *name)
227
593
  {
228
- int fd = mkstemp (name);
594
+ int fd;
595
+ fd = memfd_create (name, MFD_CLOEXEC);
596
+ return fd;
597
+ }
598
+ #endif
599
+
600
+ /* Open a temporary file name, and immediately unlink it. */
601
+ static int
602
+ open_temp_exec_file_name (char *name, int flags MAYBE_UNUSED)
603
+ {
604
+ int fd;
605
+
606
+ #ifdef HAVE_MKOSTEMP
607
+ fd = mkostemp (name, flags);
608
+ #else
609
+ fd = mkstemp (name);
610
+ #endif
229
611
 
230
612
  if (fd != -1)
231
613
  unlink (name);
@@ -238,8 +620,30 @@ static int
238
620
  open_temp_exec_file_dir (const char *dir)
239
621
  {
240
622
  static const char suffix[] = "/ffiXXXXXX";
241
- int lendir = strlen (dir);
242
- char *tempname = __builtin_alloca (lendir + sizeof (suffix));
623
+ int lendir, flags;
624
+ char *tempname;
625
+ #ifdef O_TMPFILE
626
+ int fd;
627
+ #endif
628
+
629
+ #ifdef O_CLOEXEC
630
+ flags = O_CLOEXEC;
631
+ #else
632
+ flags = 0;
633
+ #endif
634
+
635
+ #ifdef O_TMPFILE
636
+ fd = open (dir, flags | O_RDWR | O_EXCL | O_TMPFILE, 0700);
637
+ /* If the running system does not support the O_TMPFILE flag then retry without it. */
638
+ if (fd != -1 || (errno != EINVAL && errno != EISDIR && errno != EOPNOTSUPP)) {
639
+ return fd;
640
+ } else {
641
+ errno = 0;
642
+ }
643
+ #endif
644
+
645
+ lendir = (int) strlen (dir);
646
+ tempname = __builtin_alloca (lendir + sizeof (suffix));
243
647
 
244
648
  if (!tempname)
245
649
  return -1;
@@ -247,7 +651,7 @@ open_temp_exec_file_dir (const char *dir)
247
651
  memcpy (tempname, dir, lendir);
248
652
  memcpy (tempname + lendir, suffix, sizeof (suffix));
249
653
 
250
- return open_temp_exec_file_name (tempname);
654
+ return open_temp_exec_file_name (tempname, flags);
251
655
  }
252
656
 
253
657
  /* Open a temporary file in the directory in the named environment
@@ -296,7 +700,7 @@ open_temp_exec_file_mnt (const char *mounts)
296
700
  struct mntent mnt;
297
701
  char buf[MAXPATHLEN * 3];
298
702
 
299
- if (getmntent_r (last_mntent, &mnt, buf, sizeof (buf)))
703
+ if (getmntent_r (last_mntent, &mnt, buf, sizeof (buf)) == NULL)
300
704
  return -1;
301
705
 
302
706
  if (hasmntopt (&mnt, "ro")
@@ -320,6 +724,10 @@ static struct
320
724
  const char *arg;
321
725
  int repeat;
322
726
  } open_temp_exec_file_opts[] = {
727
+ #ifdef HAVE_MEMFD_CREATE
728
+ { open_temp_exec_file_memfd, "libffi", 0 },
729
+ #endif
730
+ { open_temp_exec_file_env, "LIBFFI_TMPDIR", 0 },
323
731
  { open_temp_exec_file_env, "TMPDIR", 0 },
324
732
  { open_temp_exec_file_dir, "/tmp", 0 },
325
733
  { open_temp_exec_file_dir, "/var/tmp", 0 },
@@ -356,8 +764,8 @@ open_temp_exec_file_opts_next (void)
356
764
  }
357
765
 
358
766
  /* Return a file descriptor of a temporary zero-sized file in a
359
- writable and exexutable filesystem. */
360
- static int
767
+ writable and executable filesystem. */
768
+ int
361
769
  open_temp_exec_file (void)
362
770
  {
363
771
  int fd;
@@ -379,6 +787,36 @@ open_temp_exec_file (void)
379
787
  return fd;
380
788
  }
381
789
 
790
+ /* We need to allocate space in a file that will be backing a writable
791
+ mapping. Several problems exist with the usual approaches:
792
+ - fallocate() is Linux-only
793
+ - posix_fallocate() is not available on all platforms
794
+ - ftruncate() does not allocate space on filesystems with sparse files
795
+ Failure to allocate the space will cause SIGBUS to be thrown when
796
+ the mapping is subsequently written to. */
797
+ static int
798
+ allocate_space (int fd, off_t len)
799
+ {
800
+ static long page_size;
801
+
802
+ /* Obtain system page size. */
803
+ if (!page_size)
804
+ page_size = sysconf(_SC_PAGESIZE);
805
+
806
+ unsigned char buf[page_size];
807
+ memset (buf, 0, page_size);
808
+
809
+ while (len > 0)
810
+ {
811
+ off_t to_write = (len < page_size) ? len : page_size;
812
+ if (write (fd, buf, to_write) < to_write)
813
+ return -1;
814
+ len -= to_write;
815
+ }
816
+
817
+ return 0;
818
+ }
819
+
382
820
  /* Map in a chunk of memory from the temporary exec file into separate
383
821
  locations in the virtual memory address space, one writable and one
384
822
  executable. Returns the address of the writable portion, after
@@ -400,7 +838,7 @@ dlmmap_locked (void *start, size_t length, int prot, int flags, off_t offset)
400
838
 
401
839
  offset = execsize;
402
840
 
403
- if (ftruncate (execfd, offset + length))
841
+ if (allocate_space (execfd, length))
404
842
  return MFAIL;
405
843
 
406
844
  flags &= ~(MAP_PRIVATE | MAP_ANONYMOUS);
@@ -415,7 +853,13 @@ dlmmap_locked (void *start, size_t length, int prot, int flags, off_t offset)
415
853
  close (execfd);
416
854
  goto retry_open;
417
855
  }
418
- ftruncate (execfd, offset);
856
+ if (ftruncate (execfd, offset) != 0)
857
+ {
858
+ /* Fixme : Error logs can be added here. Returning an error for
859
+ * ftruncte() will not add any advantage as it is being
860
+ * validating in the error case. */
861
+ }
862
+
419
863
  return MFAIL;
420
864
  }
421
865
  else if (!offset
@@ -427,7 +871,12 @@ dlmmap_locked (void *start, size_t length, int prot, int flags, off_t offset)
427
871
  if (start == MFAIL)
428
872
  {
429
873
  munmap (ptr, length);
430
- ftruncate (execfd, offset);
874
+ if (ftruncate (execfd, offset) != 0)
875
+ {
876
+ /* Fixme : Error logs can be added here. Returning an error for
877
+ * ftruncte() will not add any advantage as it is being
878
+ * validating in the error case. */
879
+ }
431
880
  return start;
432
881
  }
433
882
 
@@ -451,11 +900,29 @@ dlmmap (void *start, size_t length, int prot,
451
900
  && flags == (MAP_PRIVATE | MAP_ANONYMOUS)
452
901
  && fd == -1 && offset == 0);
453
902
 
454
- #if FFI_CLOSURE_TEST
455
- printf ("mapping in %zi\n", length);
456
- #endif
903
+ if (execfd == -1 && ffi_tramp_is_supported ())
904
+ {
905
+ ptr = mmap (start, length, prot & ~PROT_EXEC, flags, fd, offset);
906
+ return ptr;
907
+ }
457
908
 
458
- if (execfd == -1 && !is_selinux_enabled ())
909
+ /* -1 != execfd hints that we already decided to use dlmmap_locked
910
+ last time. */
911
+ if (execfd == -1 && is_mprotect_enabled ())
912
+ {
913
+ #ifdef FFI_MMAP_EXEC_EMUTRAMP_PAX
914
+ if (is_emutramp_enabled ())
915
+ {
916
+ /* emutramp requires the kernel recognizing the trampoline pattern
917
+ generated by ffi_prep_closure_loc; there is no way to test
918
+ in advance whether this will work, so this is experimental. */
919
+ ptr = mmap (start, length, prot & ~PROT_EXEC, flags, fd, offset);
920
+ return ptr;
921
+ }
922
+ #endif
923
+ /* fallback to dlmmap_locked. */
924
+ }
925
+ else if (execfd == -1 && !is_selinux_enabled ())
459
926
  {
460
927
  ptr = mmap (start, length, prot | PROT_EXEC, flags, fd, offset);
461
928
 
@@ -468,39 +935,13 @@ dlmmap (void *start, size_t length, int prot,
468
935
  MREMAP_DUP and prot at this point. */
469
936
  }
470
937
 
471
- if (execsize == 0 || execfd == -1)
472
- {
473
- pthread_mutex_lock (&open_temp_exec_file_mutex);
474
- ptr = dlmmap_locked (start, length, prot, flags, offset);
475
- pthread_mutex_unlock (&open_temp_exec_file_mutex);
476
-
477
- return ptr;
478
- }
479
-
480
- return dlmmap_locked (start, length, prot, flags, offset);
481
- }
482
-
483
- #else
938
+ pthread_mutex_lock (&open_temp_exec_file_mutex);
939
+ ptr = dlmmap_locked (start, length, prot, flags, offset);
940
+ pthread_mutex_unlock (&open_temp_exec_file_mutex);
484
941
 
485
- static void *
486
- dlmmap (void *start, size_t length, int prot,
487
- int flags, int fd, off_t offset)
488
- {
489
-
490
- assert (start == NULL && length % malloc_getpagesize == 0
491
- && prot == (PROT_READ | PROT_WRITE)
492
- && flags == (MAP_PRIVATE | MAP_ANONYMOUS)
493
- && fd == -1 && offset == 0);
494
-
495
- #if FFI_CLOSURE_TEST
496
- printf ("mapping in %zi\n", length);
497
- #endif
498
-
499
- return mmap (start, length, prot | PROT_EXEC, flags, fd, offset);
942
+ return ptr;
500
943
  }
501
944
 
502
- #endif
503
-
504
945
  /* Release memory at the given address, as well as the corresponding
505
946
  executable page if it's separate. */
506
947
  static int
@@ -515,10 +956,6 @@ dlmunmap (void *start, size_t length)
515
956
  msegmentptr seg = segment_holding (gm, start);
516
957
  void *code;
517
958
 
518
- #if FFI_CLOSURE_TEST
519
- printf ("unmapping %zi\n", length);
520
- #endif
521
-
522
959
  if (seg && (code = add_segment_exec_offset (start, seg)) != start)
523
960
  {
524
961
  int ret = munmap (code, length);
@@ -545,7 +982,7 @@ segment_holding_code (mstate m, char* addr)
545
982
  }
546
983
  #endif
547
984
 
548
- #endif /* !(defined(X86_WIN32) || defined(X86_WIN64)) || defined (__CYGWIN__) */
985
+ #endif /* !(defined(_WIN32) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX) */
549
986
 
550
987
  /* Allocate a chunk of memory with the given size. Returns a pointer
551
988
  to the writable address, and sets *CODE to the executable
@@ -553,7 +990,7 @@ segment_holding_code (mstate m, char* addr)
553
990
  void *
554
991
  ffi_closure_alloc (size_t size, void **code)
555
992
  {
556
- void *ptr;
993
+ void *ptr, *ftramp;
557
994
 
558
995
  if (!code)
559
996
  return NULL;
@@ -564,12 +1001,41 @@ ffi_closure_alloc (size_t size, void **code)
564
1001
  {
565
1002
  msegmentptr seg = segment_holding (gm, ptr);
566
1003
 
567
- *code = add_segment_exec_offset (ptr, seg);
1004
+ *code = FFI_FN (add_segment_exec_offset (ptr, seg));
1005
+ if (!ffi_tramp_is_supported ())
1006
+ return ptr;
1007
+
1008
+ ftramp = ffi_tramp_alloc (0);
1009
+ if (ftramp == NULL)
1010
+ {
1011
+ dlfree (ptr);
1012
+ return NULL;
1013
+ }
1014
+ *code = FFI_FN (ffi_tramp_get_addr (ftramp));
1015
+ ((ffi_closure *) ptr)->ftramp = ftramp;
568
1016
  }
569
1017
 
570
1018
  return ptr;
571
1019
  }
572
1020
 
1021
+ void *
1022
+ ffi_data_to_code_pointer (void *data)
1023
+ {
1024
+ msegmentptr seg = segment_holding (gm, data);
1025
+ /* We expect closures to be allocated with ffi_closure_alloc(), in
1026
+ which case seg will be non-NULL. However, some users take on the
1027
+ burden of managing this memory themselves, in which case this
1028
+ we'll just return data. */
1029
+ if (seg)
1030
+ {
1031
+ if (!ffi_tramp_is_supported ())
1032
+ return add_segment_exec_offset (data, seg);
1033
+ return ffi_tramp_get_addr (((ffi_closure *) data)->ftramp);
1034
+ }
1035
+ else
1036
+ return data;
1037
+ }
1038
+
573
1039
  /* Release a chunk of memory allocated with ffi_closure_alloc. If
574
1040
  FFI_CLOSURE_FREE_CODE is nonzero, the given address can be the
575
1041
  writable or the executable address given. Otherwise, only the
@@ -583,30 +1049,19 @@ ffi_closure_free (void *ptr)
583
1049
  if (seg)
584
1050
  ptr = sub_segment_exec_offset (ptr, seg);
585
1051
  #endif
1052
+ if (ffi_tramp_is_supported ())
1053
+ ffi_tramp_free (((ffi_closure *) ptr)->ftramp);
586
1054
 
587
1055
  dlfree (ptr);
588
1056
  }
589
1057
 
590
-
591
- #if FFI_CLOSURE_TEST
592
- /* Do some internal sanity testing to make sure allocation and
593
- deallocation of pages are working as intended. */
594
- int main ()
595
- {
596
- void *p[3];
597
- #define GET(idx, len) do { p[idx] = dlmalloc (len); printf ("allocated %zi for p[%i]\n", (len), (idx)); } while (0)
598
- #define PUT(idx) do { printf ("freeing p[%i]\n", (idx)); dlfree (p[idx]); } while (0)
599
- GET (0, malloc_getpagesize / 2);
600
- GET (1, 2 * malloc_getpagesize - 64 * sizeof (void*));
601
- PUT (1);
602
- GET (1, 2 * malloc_getpagesize);
603
- GET (2, malloc_getpagesize / 2);
604
- PUT (1);
605
- PUT (0);
606
- PUT (2);
607
- return 0;
1058
+ int
1059
+ ffi_tramp_is_present (void *ptr)
1060
+ {
1061
+ msegmentptr seg = segment_holding (gm, ptr);
1062
+ return seg != NULL && ffi_tramp_is_supported();
608
1063
  }
609
- #endif /* FFI_CLOSURE_TEST */
1064
+
610
1065
  # else /* ! FFI_MMAP_EXEC_WRIT */
611
1066
 
612
1067
  /* On many systems, memory returned by malloc is writable and
@@ -617,10 +1072,14 @@ int main ()
617
1072
  void *
618
1073
  ffi_closure_alloc (size_t size, void **code)
619
1074
  {
1075
+ void *c;
1076
+
620
1077
  if (!code)
621
1078
  return NULL;
622
1079
 
623
- return *code = malloc (size);
1080
+ c = malloc (size);
1081
+ *code = FFI_FN (c);
1082
+ return c;
624
1083
  }
625
1084
 
626
1085
  void
@@ -629,5 +1088,20 @@ ffi_closure_free (void *ptr)
629
1088
  free (ptr);
630
1089
  }
631
1090
 
1091
+ void *
1092
+ ffi_data_to_code_pointer (void *data)
1093
+ {
1094
+ return data;
1095
+ }
1096
+
1097
+ int
1098
+ ffi_tramp_is_present (__attribute__((unused)) void *ptr)
1099
+ {
1100
+ return 0;
1101
+ }
1102
+
632
1103
  # endif /* ! FFI_MMAP_EXEC_WRIT */
633
1104
  #endif /* FFI_CLOSURES */
1105
+
1106
+ #endif /* NetBSD with PROT_MPROTECT */
1107
+ #endif /* __EMSCRIPTEN__ */