ffi 1.11.2

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 (542) hide show
  1. checksums.yaml +7 -0
  2. data/.appveyor.yml +27 -0
  3. data/.gitignore +25 -0
  4. data/.gitmodules +4 -0
  5. data/.travis.yml +42 -0
  6. data/.yardopts +5 -0
  7. data/CHANGELOG.md +147 -0
  8. data/COPYING +49 -0
  9. data/Gemfile +15 -0
  10. data/LICENSE +24 -0
  11. data/LICENSE.SPECS +22 -0
  12. data/README.md +115 -0
  13. data/Rakefile +196 -0
  14. data/ext/ffi_c/AbstractMemory.c +1109 -0
  15. data/ext/ffi_c/AbstractMemory.h +175 -0
  16. data/ext/ffi_c/ArrayType.c +162 -0
  17. data/ext/ffi_c/ArrayType.h +59 -0
  18. data/ext/ffi_c/Buffer.c +365 -0
  19. data/ext/ffi_c/Call.c +503 -0
  20. data/ext/ffi_c/Call.h +107 -0
  21. data/ext/ffi_c/ClosurePool.c +283 -0
  22. data/ext/ffi_c/ClosurePool.h +57 -0
  23. data/ext/ffi_c/DynamicLibrary.c +339 -0
  24. data/ext/ffi_c/DynamicLibrary.h +98 -0
  25. data/ext/ffi_c/Function.c +917 -0
  26. data/ext/ffi_c/Function.h +87 -0
  27. data/ext/ffi_c/FunctionInfo.c +271 -0
  28. data/ext/ffi_c/LastError.c +229 -0
  29. data/ext/ffi_c/LastError.h +47 -0
  30. data/ext/ffi_c/LongDouble.c +63 -0
  31. data/ext/ffi_c/LongDouble.h +51 -0
  32. data/ext/ffi_c/MappedType.c +168 -0
  33. data/ext/ffi_c/MappedType.h +59 -0
  34. data/ext/ffi_c/MemoryPointer.c +197 -0
  35. data/ext/ffi_c/MemoryPointer.h +53 -0
  36. data/ext/ffi_c/MethodHandle.c +358 -0
  37. data/ext/ffi_c/MethodHandle.h +55 -0
  38. data/ext/ffi_c/Platform.c +82 -0
  39. data/ext/ffi_c/Platform.h +45 -0
  40. data/ext/ffi_c/Pointer.c +508 -0
  41. data/ext/ffi_c/Pointer.h +63 -0
  42. data/ext/ffi_c/Struct.c +829 -0
  43. data/ext/ffi_c/Struct.h +106 -0
  44. data/ext/ffi_c/StructByValue.c +150 -0
  45. data/ext/ffi_c/StructByValue.h +55 -0
  46. data/ext/ffi_c/StructLayout.c +698 -0
  47. data/ext/ffi_c/Thread.c +137 -0
  48. data/ext/ffi_c/Thread.h +84 -0
  49. data/ext/ffi_c/Type.c +379 -0
  50. data/ext/ffi_c/Type.h +61 -0
  51. data/ext/ffi_c/Types.c +139 -0
  52. data/ext/ffi_c/Types.h +89 -0
  53. data/ext/ffi_c/Variadic.c +298 -0
  54. data/ext/ffi_c/compat.h +78 -0
  55. data/ext/ffi_c/extconf.rb +86 -0
  56. data/ext/ffi_c/ffi.c +93 -0
  57. data/ext/ffi_c/libffi.bsd.mk +40 -0
  58. data/ext/ffi_c/libffi.darwin.mk +105 -0
  59. data/ext/ffi_c/libffi.gnu.mk +32 -0
  60. data/ext/ffi_c/libffi.mk +18 -0
  61. data/ext/ffi_c/libffi.vc.mk +26 -0
  62. data/ext/ffi_c/libffi.vc64.mk +26 -0
  63. data/ext/ffi_c/libffi/.appveyor.yml +66 -0
  64. data/ext/ffi_c/libffi/.gitattributes +4 -0
  65. data/ext/ffi_c/libffi/.github/issue_template.md +10 -0
  66. data/ext/ffi_c/libffi/.gitignore +38 -0
  67. data/ext/ffi_c/libffi/.travis.yml +63 -0
  68. data/ext/ffi_c/libffi/.travis/ar-lib +270 -0
  69. data/ext/ffi_c/libffi/.travis/build-in-container.sh +22 -0
  70. data/ext/ffi_c/libffi/.travis/build.sh +110 -0
  71. data/ext/ffi_c/libffi/.travis/compile +351 -0
  72. data/ext/ffi_c/libffi/.travis/install.sh +43 -0
  73. data/ext/ffi_c/libffi/.travis/moxie-sim.exp +60 -0
  74. data/ext/ffi_c/libffi/.travis/site.exp +18 -0
  75. data/ext/ffi_c/libffi/ChangeLog.libffi +584 -0
  76. data/ext/ffi_c/libffi/ChangeLog.libffi-3.1 +6000 -0
  77. data/ext/ffi_c/libffi/ChangeLog.libgcj +40 -0
  78. data/ext/ffi_c/libffi/ChangeLog.v1 +764 -0
  79. data/ext/ffi_c/libffi/LICENSE +21 -0
  80. data/ext/ffi_c/libffi/LICENSE-BUILDTOOLS +353 -0
  81. data/ext/ffi_c/libffi/Makefile.am +158 -0
  82. data/ext/ffi_c/libffi/README.md +470 -0
  83. data/ext/ffi_c/libffi/acinclude.m4 +479 -0
  84. data/ext/ffi_c/libffi/autogen.sh +2 -0
  85. data/ext/ffi_c/libffi/config.guess +1466 -0
  86. data/ext/ffi_c/libffi/config.sub +1836 -0
  87. data/ext/ffi_c/libffi/configure.ac +394 -0
  88. data/ext/ffi_c/libffi/configure.host +303 -0
  89. data/ext/ffi_c/libffi/generate-darwin-source-and-headers.py +203 -0
  90. data/ext/ffi_c/libffi/include/Makefile.am +9 -0
  91. data/ext/ffi_c/libffi/include/ffi.h.in +515 -0
  92. data/ext/ffi_c/libffi/include/ffi_cfi.h +55 -0
  93. data/ext/ffi_c/libffi/include/ffi_common.h +153 -0
  94. data/ext/ffi_c/libffi/libffi.map.in +80 -0
  95. data/ext/ffi_c/libffi/libffi.pc.in +11 -0
  96. data/ext/ffi_c/libffi/libffi.xcodeproj/project.pbxproj +1043 -0
  97. data/ext/ffi_c/libffi/libtool-version +29 -0
  98. data/ext/ffi_c/libffi/m4/asmcfi.m4 +13 -0
  99. data/ext/ffi_c/libffi/m4/ax_append_flag.m4 +71 -0
  100. data/ext/ffi_c/libffi/m4/ax_cc_maxopt.m4 +194 -0
  101. data/ext/ffi_c/libffi/m4/ax_cflags_warn_all.m4 +122 -0
  102. data/ext/ffi_c/libffi/m4/ax_check_compile_flag.m4 +74 -0
  103. data/ext/ffi_c/libffi/m4/ax_compiler_vendor.m4 +87 -0
  104. data/ext/ffi_c/libffi/m4/ax_configure_args.m4 +70 -0
  105. data/ext/ffi_c/libffi/m4/ax_enable_builddir.m4 +302 -0
  106. data/ext/ffi_c/libffi/m4/ax_gcc_archflag.m4 +263 -0
  107. data/ext/ffi_c/libffi/m4/ax_gcc_x86_cpuid.m4 +89 -0
  108. data/ext/ffi_c/libffi/m4/ax_require_defined.m4 +37 -0
  109. data/ext/ffi_c/libffi/make_sunver.pl +333 -0
  110. data/ext/ffi_c/libffi/man/Makefile.am +8 -0
  111. data/ext/ffi_c/libffi/man/ffi.3 +41 -0
  112. data/ext/ffi_c/libffi/man/ffi_call.3 +103 -0
  113. data/ext/ffi_c/libffi/man/ffi_prep_cif.3 +68 -0
  114. data/ext/ffi_c/libffi/man/ffi_prep_cif_var.3 +73 -0
  115. data/ext/ffi_c/libffi/msvc_build/aarch64/Ffi_staticLib.sln +33 -0
  116. data/ext/ffi_c/libffi/msvc_build/aarch64/Ffi_staticLib.vcxproj +130 -0
  117. data/ext/ffi_c/libffi/msvc_build/aarch64/Ffi_staticLib.vcxproj.filters +57 -0
  118. data/ext/ffi_c/libffi/msvc_build/aarch64/Ffi_staticLib.vcxproj.user +4 -0
  119. data/ext/ffi_c/libffi/msvc_build/aarch64/aarch64_include/ffi.h +511 -0
  120. data/ext/ffi_c/libffi/msvcc.sh +353 -0
  121. data/ext/ffi_c/libffi/src/aarch64/ffi.c +1009 -0
  122. data/ext/ffi_c/libffi/src/aarch64/ffitarget.h +92 -0
  123. data/ext/ffi_c/libffi/src/aarch64/internal.h +67 -0
  124. data/ext/ffi_c/libffi/src/aarch64/sysv.S +440 -0
  125. data/ext/ffi_c/libffi/src/aarch64/win64_armasm.S +506 -0
  126. data/ext/ffi_c/libffi/src/alpha/ffi.c +521 -0
  127. data/ext/ffi_c/libffi/src/alpha/ffitarget.h +57 -0
  128. data/ext/ffi_c/libffi/src/alpha/internal.h +23 -0
  129. data/ext/ffi_c/libffi/src/alpha/osf.S +282 -0
  130. data/ext/ffi_c/libffi/src/arc/arcompact.S +135 -0
  131. data/ext/ffi_c/libffi/src/arc/ffi.c +266 -0
  132. data/ext/ffi_c/libffi/src/arc/ffitarget.h +53 -0
  133. data/ext/ffi_c/libffi/src/arm/ffi.c +854 -0
  134. data/ext/ffi_c/libffi/src/arm/ffitarget.h +89 -0
  135. data/ext/ffi_c/libffi/src/arm/internal.h +7 -0
  136. data/ext/ffi_c/libffi/src/arm/sysv.S +385 -0
  137. data/ext/ffi_c/libffi/src/arm/sysv_msvc_arm32.S +311 -0
  138. data/ext/ffi_c/libffi/src/avr32/ffi.c +423 -0
  139. data/ext/ffi_c/libffi/src/avr32/ffitarget.h +55 -0
  140. data/ext/ffi_c/libffi/src/avr32/sysv.S +208 -0
  141. data/ext/ffi_c/libffi/src/bfin/ffi.c +196 -0
  142. data/ext/ffi_c/libffi/src/bfin/ffitarget.h +43 -0
  143. data/ext/ffi_c/libffi/src/bfin/sysv.S +179 -0
  144. data/ext/ffi_c/libffi/src/closures.c +990 -0
  145. data/ext/ffi_c/libffi/src/cris/ffi.c +386 -0
  146. data/ext/ffi_c/libffi/src/cris/ffitarget.h +56 -0
  147. data/ext/ffi_c/libffi/src/cris/sysv.S +215 -0
  148. data/ext/ffi_c/libffi/src/debug.c +64 -0
  149. data/ext/ffi_c/libffi/src/dlmalloc.c +5166 -0
  150. data/ext/ffi_c/libffi/src/frv/eabi.S +128 -0
  151. data/ext/ffi_c/libffi/src/frv/ffi.c +292 -0
  152. data/ext/ffi_c/libffi/src/frv/ffitarget.h +62 -0
  153. data/ext/ffi_c/libffi/src/ia64/ffi.c +604 -0
  154. data/ext/ffi_c/libffi/src/ia64/ffitarget.h +56 -0
  155. data/ext/ffi_c/libffi/src/ia64/ia64_flags.h +40 -0
  156. data/ext/ffi_c/libffi/src/ia64/unix.S +567 -0
  157. data/ext/ffi_c/libffi/src/java_raw_api.c +374 -0
  158. data/ext/ffi_c/libffi/src/m32r/ffi.c +232 -0
  159. data/ext/ffi_c/libffi/src/m32r/ffitarget.h +53 -0
  160. data/ext/ffi_c/libffi/src/m32r/sysv.S +121 -0
  161. data/ext/ffi_c/libffi/src/m68k/ffi.c +362 -0
  162. data/ext/ffi_c/libffi/src/m68k/ffitarget.h +54 -0
  163. data/ext/ffi_c/libffi/src/m68k/sysv.S +357 -0
  164. data/ext/ffi_c/libffi/src/m88k/ffi.c +400 -0
  165. data/ext/ffi_c/libffi/src/m88k/ffitarget.h +49 -0
  166. data/ext/ffi_c/libffi/src/m88k/obsd.S +209 -0
  167. data/ext/ffi_c/libffi/src/metag/ffi.c +330 -0
  168. data/ext/ffi_c/libffi/src/metag/ffitarget.h +53 -0
  169. data/ext/ffi_c/libffi/src/metag/sysv.S +311 -0
  170. data/ext/ffi_c/libffi/src/microblaze/ffi.c +321 -0
  171. data/ext/ffi_c/libffi/src/microblaze/ffitarget.h +53 -0
  172. data/ext/ffi_c/libffi/src/microblaze/sysv.S +302 -0
  173. data/ext/ffi_c/libffi/src/mips/ffi.c +1130 -0
  174. data/ext/ffi_c/libffi/src/mips/ffitarget.h +244 -0
  175. data/ext/ffi_c/libffi/src/mips/n32.S +663 -0
  176. data/ext/ffi_c/libffi/src/mips/o32.S +502 -0
  177. data/ext/ffi_c/libffi/src/moxie/eabi.S +101 -0
  178. data/ext/ffi_c/libffi/src/moxie/ffi.c +285 -0
  179. data/ext/ffi_c/libffi/src/moxie/ffitarget.h +52 -0
  180. data/ext/ffi_c/libffi/src/nios2/ffi.c +304 -0
  181. data/ext/ffi_c/libffi/src/nios2/ffitarget.h +52 -0
  182. data/ext/ffi_c/libffi/src/nios2/sysv.S +136 -0
  183. data/ext/ffi_c/libffi/src/or1k/ffi.c +328 -0
  184. data/ext/ffi_c/libffi/src/or1k/ffitarget.h +58 -0
  185. data/ext/ffi_c/libffi/src/or1k/sysv.S +107 -0
  186. data/ext/ffi_c/libffi/src/pa/ffi.c +719 -0
  187. data/ext/ffi_c/libffi/src/pa/ffitarget.h +85 -0
  188. data/ext/ffi_c/libffi/src/pa/hpux32.S +368 -0
  189. data/ext/ffi_c/libffi/src/pa/linux.S +378 -0
  190. data/ext/ffi_c/libffi/src/powerpc/aix.S +566 -0
  191. data/ext/ffi_c/libffi/src/powerpc/aix_closure.S +694 -0
  192. data/ext/ffi_c/libffi/src/powerpc/asm.h +125 -0
  193. data/ext/ffi_c/libffi/src/powerpc/darwin.S +378 -0
  194. data/ext/ffi_c/libffi/src/powerpc/darwin_closure.S +571 -0
  195. data/ext/ffi_c/libffi/src/powerpc/ffi.c +174 -0
  196. data/ext/ffi_c/libffi/src/powerpc/ffi_darwin.c +1440 -0
  197. data/ext/ffi_c/libffi/src/powerpc/ffi_linux64.c +1007 -0
  198. data/ext/ffi_c/libffi/src/powerpc/ffi_powerpc.h +94 -0
  199. data/ext/ffi_c/libffi/src/powerpc/ffi_sysv.c +923 -0
  200. data/ext/ffi_c/libffi/src/powerpc/ffitarget.h +198 -0
  201. data/ext/ffi_c/libffi/src/powerpc/linux64.S +228 -0
  202. data/ext/ffi_c/libffi/src/powerpc/linux64_closure.S +488 -0
  203. data/ext/ffi_c/libffi/src/powerpc/ppc_closure.S +397 -0
  204. data/ext/ffi_c/libffi/src/powerpc/sysv.S +175 -0
  205. data/ext/ffi_c/libffi/src/prep_cif.c +263 -0
  206. data/ext/ffi_c/libffi/src/raw_api.c +267 -0
  207. data/ext/ffi_c/libffi/src/riscv/ffi.c +481 -0
  208. data/ext/ffi_c/libffi/src/riscv/ffitarget.h +69 -0
  209. data/ext/ffi_c/libffi/src/riscv/sysv.S +293 -0
  210. data/ext/ffi_c/libffi/src/s390/ffi.c +756 -0
  211. data/ext/ffi_c/libffi/src/s390/ffitarget.h +70 -0
  212. data/ext/ffi_c/libffi/src/s390/internal.h +11 -0
  213. data/ext/ffi_c/libffi/src/s390/sysv.S +325 -0
  214. data/ext/ffi_c/libffi/src/sh/ffi.c +717 -0
  215. data/ext/ffi_c/libffi/src/sh/ffitarget.h +54 -0
  216. data/ext/ffi_c/libffi/src/sh/sysv.S +850 -0
  217. data/ext/ffi_c/libffi/src/sh64/ffi.c +469 -0
  218. data/ext/ffi_c/libffi/src/sh64/ffitarget.h +58 -0
  219. data/ext/ffi_c/libffi/src/sh64/sysv.S +539 -0
  220. data/ext/ffi_c/libffi/src/sparc/ffi.c +468 -0
  221. data/ext/ffi_c/libffi/src/sparc/ffi64.c +608 -0
  222. data/ext/ffi_c/libffi/src/sparc/ffitarget.h +81 -0
  223. data/ext/ffi_c/libffi/src/sparc/internal.h +26 -0
  224. data/ext/ffi_c/libffi/src/sparc/v8.S +443 -0
  225. data/ext/ffi_c/libffi/src/sparc/v9.S +440 -0
  226. data/ext/ffi_c/libffi/src/tile/ffi.c +355 -0
  227. data/ext/ffi_c/libffi/src/tile/ffitarget.h +65 -0
  228. data/ext/ffi_c/libffi/src/tile/tile.S +360 -0
  229. data/ext/ffi_c/libffi/src/types.c +108 -0
  230. data/ext/ffi_c/libffi/src/vax/elfbsd.S +195 -0
  231. data/ext/ffi_c/libffi/src/vax/ffi.c +276 -0
  232. data/ext/ffi_c/libffi/src/vax/ffitarget.h +49 -0
  233. data/ext/ffi_c/libffi/src/x86/asmnames.h +30 -0
  234. data/ext/ffi_c/libffi/src/x86/ffi.c +761 -0
  235. data/ext/ffi_c/libffi/src/x86/ffi64.c +886 -0
  236. data/ext/ffi_c/libffi/src/x86/ffitarget.h +147 -0
  237. data/ext/ffi_c/libffi/src/x86/ffiw64.c +311 -0
  238. data/ext/ffi_c/libffi/src/x86/internal.h +29 -0
  239. data/ext/ffi_c/libffi/src/x86/internal64.h +22 -0
  240. data/ext/ffi_c/libffi/src/x86/sysv.S +1129 -0
  241. data/ext/ffi_c/libffi/src/x86/sysv_intel.S +995 -0
  242. data/ext/ffi_c/libffi/src/x86/unix64.S +566 -0
  243. data/ext/ffi_c/libffi/src/x86/win64.S +237 -0
  244. data/ext/ffi_c/libffi/src/x86/win64_intel.S +237 -0
  245. data/ext/ffi_c/libffi/src/xtensa/ffi.c +298 -0
  246. data/ext/ffi_c/libffi/src/xtensa/ffitarget.h +53 -0
  247. data/ext/ffi_c/libffi/src/xtensa/sysv.S +258 -0
  248. data/ext/ffi_c/libffi/stamp-h.in +1 -0
  249. data/ext/ffi_c/libffi/testsuite/Makefile.am +119 -0
  250. data/ext/ffi_c/libffi/testsuite/config/default.exp +1 -0
  251. data/ext/ffi_c/libffi/testsuite/lib/libffi.exp +657 -0
  252. data/ext/ffi_c/libffi/testsuite/lib/target-libpath.exp +283 -0
  253. data/ext/ffi_c/libffi/testsuite/lib/wrapper.exp +45 -0
  254. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/Makefile +28 -0
  255. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/README +78 -0
  256. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/alignof.h +50 -0
  257. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/bhaible.exp +58 -0
  258. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/test-call.c +1745 -0
  259. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/test-callback.c +2885 -0
  260. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/testcases.c +743 -0
  261. data/ext/ffi_c/libffi/testsuite/libffi.call/align_mixed.c +46 -0
  262. data/ext/ffi_c/libffi/testsuite/libffi.call/align_stdcall.c +46 -0
  263. data/ext/ffi_c/libffi/testsuite/libffi.call/call.exp +43 -0
  264. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn0.c +89 -0
  265. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn1.c +81 -0
  266. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn2.c +81 -0
  267. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn3.c +82 -0
  268. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn4.c +89 -0
  269. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn5.c +92 -0
  270. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn6.c +90 -0
  271. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_loc_fn0.c +95 -0
  272. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_simple.c +55 -0
  273. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_12byte.c +94 -0
  274. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_16byte.c +95 -0
  275. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_18byte.c +96 -0
  276. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_19byte.c +102 -0
  277. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_1_1byte.c +89 -0
  278. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_20byte.c +91 -0
  279. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_20byte1.c +93 -0
  280. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_24byte.c +113 -0
  281. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_2byte.c +90 -0
  282. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3_1byte.c +95 -0
  283. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3byte1.c +90 -0
  284. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3byte2.c +90 -0
  285. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3float.c +95 -0
  286. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_4_1byte.c +98 -0
  287. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_4byte.c +90 -0
  288. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_5_1_byte.c +109 -0
  289. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_5byte.c +98 -0
  290. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_64byte.c +124 -0
  291. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_6_1_byte.c +113 -0
  292. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_6byte.c +99 -0
  293. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_7_1_byte.c +117 -0
  294. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_7byte.c +97 -0
  295. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_8byte.c +88 -0
  296. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_9byte1.c +90 -0
  297. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_9byte2.c +91 -0
  298. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_double.c +93 -0
  299. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_float.c +91 -0
  300. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble.c +92 -0
  301. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble_split.c +132 -0
  302. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble_split2.c +115 -0
  303. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_pointer.c +95 -0
  304. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint16.c +91 -0
  305. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint32.c +91 -0
  306. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint64.c +92 -0
  307. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint16.c +91 -0
  308. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint32.c +91 -0
  309. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint64.c +93 -0
  310. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_dbls_struct.c +66 -0
  311. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_double.c +43 -0
  312. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_double_va.c +61 -0
  313. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_float.c +42 -0
  314. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_longdouble.c +105 -0
  315. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_longdouble_va.c +61 -0
  316. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_many_mixed_args.c +70 -0
  317. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_many_mixed_float_double.c +55 -0
  318. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_schar.c +74 -0
  319. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_sshort.c +74 -0
  320. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_sshortchar.c +86 -0
  321. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_uchar.c +91 -0
  322. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_ushort.c +74 -0
  323. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_ushortchar.c +86 -0
  324. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_pointer.c +74 -0
  325. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_pointer_stack.c +142 -0
  326. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_schar.c +44 -0
  327. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_sint.c +42 -0
  328. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_sshort.c +42 -0
  329. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_struct_va1.c +114 -0
  330. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_uchar.c +42 -0
  331. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_uchar_va.c +44 -0
  332. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_uint.c +43 -0
  333. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_uint_va.c +45 -0
  334. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_ulong_va.c +45 -0
  335. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_ulonglong.c +47 -0
  336. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_ushort.c +43 -0
  337. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_ushort_va.c +44 -0
  338. data/ext/ffi_c/libffi/testsuite/libffi.call/err_bad_abi.c +36 -0
  339. data/ext/ffi_c/libffi/testsuite/libffi.call/err_bad_typedef.c +26 -0
  340. data/ext/ffi_c/libffi/testsuite/libffi.call/ffitest.h +138 -0
  341. data/ext/ffi_c/libffi/testsuite/libffi.call/float.c +59 -0
  342. data/ext/ffi_c/libffi/testsuite/libffi.call/float1.c +60 -0
  343. data/ext/ffi_c/libffi/testsuite/libffi.call/float2.c +61 -0
  344. data/ext/ffi_c/libffi/testsuite/libffi.call/float3.c +74 -0
  345. data/ext/ffi_c/libffi/testsuite/libffi.call/float4.c +62 -0
  346. data/ext/ffi_c/libffi/testsuite/libffi.call/float_va.c +107 -0
  347. data/ext/ffi_c/libffi/testsuite/libffi.call/huge_struct.c +341 -0
  348. data/ext/ffi_c/libffi/testsuite/libffi.call/many.c +59 -0
  349. data/ext/ffi_c/libffi/testsuite/libffi.call/many2.c +57 -0
  350. data/ext/ffi_c/libffi/testsuite/libffi.call/many_double.c +70 -0
  351. data/ext/ffi_c/libffi/testsuite/libffi.call/many_mixed.c +78 -0
  352. data/ext/ffi_c/libffi/testsuite/libffi.call/negint.c +52 -0
  353. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct.c +152 -0
  354. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct1.c +161 -0
  355. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct10.c +134 -0
  356. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct11.c +121 -0
  357. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct2.c +110 -0
  358. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct3.c +111 -0
  359. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct4.c +111 -0
  360. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct5.c +112 -0
  361. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct6.c +131 -0
  362. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct7.c +111 -0
  363. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct8.c +131 -0
  364. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct9.c +131 -0
  365. data/ext/ffi_c/libffi/testsuite/libffi.call/offsets.c +46 -0
  366. data/ext/ffi_c/libffi/testsuite/libffi.call/pr1172638.c +127 -0
  367. data/ext/ffi_c/libffi/testsuite/libffi.call/problem1.c +90 -0
  368. data/ext/ffi_c/libffi/testsuite/libffi.call/promotion.c +59 -0
  369. data/ext/ffi_c/libffi/testsuite/libffi.call/pyobjc-tc.c +114 -0
  370. data/ext/ffi_c/libffi/testsuite/libffi.call/return_dbl.c +36 -0
  371. data/ext/ffi_c/libffi/testsuite/libffi.call/return_dbl1.c +43 -0
  372. data/ext/ffi_c/libffi/testsuite/libffi.call/return_dbl2.c +42 -0
  373. data/ext/ffi_c/libffi/testsuite/libffi.call/return_fl.c +35 -0
  374. data/ext/ffi_c/libffi/testsuite/libffi.call/return_fl1.c +36 -0
  375. data/ext/ffi_c/libffi/testsuite/libffi.call/return_fl2.c +49 -0
  376. data/ext/ffi_c/libffi/testsuite/libffi.call/return_fl3.c +42 -0
  377. data/ext/ffi_c/libffi/testsuite/libffi.call/return_ldl.c +34 -0
  378. data/ext/ffi_c/libffi/testsuite/libffi.call/return_ll.c +41 -0
  379. data/ext/ffi_c/libffi/testsuite/libffi.call/return_ll1.c +43 -0
  380. data/ext/ffi_c/libffi/testsuite/libffi.call/return_sc.c +36 -0
  381. data/ext/ffi_c/libffi/testsuite/libffi.call/return_sl.c +38 -0
  382. data/ext/ffi_c/libffi/testsuite/libffi.call/return_uc.c +38 -0
  383. data/ext/ffi_c/libffi/testsuite/libffi.call/return_ul.c +38 -0
  384. data/ext/ffi_c/libffi/testsuite/libffi.call/stret_large.c +145 -0
  385. data/ext/ffi_c/libffi/testsuite/libffi.call/stret_large2.c +148 -0
  386. data/ext/ffi_c/libffi/testsuite/libffi.call/stret_medium.c +124 -0
  387. data/ext/ffi_c/libffi/testsuite/libffi.call/stret_medium2.c +125 -0
  388. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen.c +44 -0
  389. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen2.c +49 -0
  390. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen3.c +49 -0
  391. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen4.c +55 -0
  392. data/ext/ffi_c/libffi/testsuite/libffi.call/struct1.c +67 -0
  393. data/ext/ffi_c/libffi/testsuite/libffi.call/struct10.c +57 -0
  394. data/ext/ffi_c/libffi/testsuite/libffi.call/struct2.c +67 -0
  395. data/ext/ffi_c/libffi/testsuite/libffi.call/struct3.c +60 -0
  396. data/ext/ffi_c/libffi/testsuite/libffi.call/struct4.c +64 -0
  397. data/ext/ffi_c/libffi/testsuite/libffi.call/struct5.c +66 -0
  398. data/ext/ffi_c/libffi/testsuite/libffi.call/struct6.c +64 -0
  399. data/ext/ffi_c/libffi/testsuite/libffi.call/struct7.c +74 -0
  400. data/ext/ffi_c/libffi/testsuite/libffi.call/struct8.c +81 -0
  401. data/ext/ffi_c/libffi/testsuite/libffi.call/struct9.c +68 -0
  402. data/ext/ffi_c/libffi/testsuite/libffi.call/testclosure.c +70 -0
  403. data/ext/ffi_c/libffi/testsuite/libffi.call/uninitialized.c +61 -0
  404. data/ext/ffi_c/libffi/testsuite/libffi.call/unwindtest.cc +117 -0
  405. data/ext/ffi_c/libffi/testsuite/libffi.call/unwindtest_ffi_call.cc +54 -0
  406. data/ext/ffi_c/libffi/testsuite/libffi.call/va_1.c +196 -0
  407. data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct1.c +121 -0
  408. data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct2.c +123 -0
  409. data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct3.c +125 -0
  410. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_align_complex.inc +91 -0
  411. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_align_complex_double.c +10 -0
  412. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_align_complex_float.c +10 -0
  413. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_align_complex_longdouble.c +10 -0
  414. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex.inc +42 -0
  415. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_double.c +10 -0
  416. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_float.c +10 -0
  417. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_longdouble.c +10 -0
  418. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_struct.inc +71 -0
  419. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_struct_double.c +10 -0
  420. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_struct_float.c +10 -0
  421. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_struct_longdouble.c +10 -0
  422. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_va.inc +80 -0
  423. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_va_double.c +10 -0
  424. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_va_float.c +16 -0
  425. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_va_longdouble.c +10 -0
  426. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex.exp +36 -0
  427. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex.inc +51 -0
  428. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_defs_double.inc +7 -0
  429. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_defs_float.inc +7 -0
  430. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_defs_longdouble.inc +7 -0
  431. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_double.c +10 -0
  432. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_float.c +10 -0
  433. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_int.c +86 -0
  434. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_longdouble.c +10 -0
  435. data/ext/ffi_c/libffi/testsuite/libffi.complex/ffitest.h +1 -0
  436. data/ext/ffi_c/libffi/testsuite/libffi.complex/many_complex.inc +78 -0
  437. data/ext/ffi_c/libffi/testsuite/libffi.complex/many_complex_double.c +10 -0
  438. data/ext/ffi_c/libffi/testsuite/libffi.complex/many_complex_float.c +10 -0
  439. data/ext/ffi_c/libffi/testsuite/libffi.complex/many_complex_longdouble.c +10 -0
  440. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex.inc +37 -0
  441. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex1.inc +41 -0
  442. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex1_double.c +10 -0
  443. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex1_float.c +10 -0
  444. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex1_longdouble.c +10 -0
  445. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex2.inc +44 -0
  446. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex2_double.c +10 -0
  447. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex2_float.c +10 -0
  448. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex2_longdouble.c +10 -0
  449. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex_double.c +10 -0
  450. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex_float.c +10 -0
  451. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex_longdouble.c +10 -0
  452. data/ext/ffi_c/libffi/testsuite/libffi.go/aa-direct.c +34 -0
  453. data/ext/ffi_c/libffi/testsuite/libffi.go/closure1.c +28 -0
  454. data/ext/ffi_c/libffi/testsuite/libffi.go/ffitest.h +1 -0
  455. data/ext/ffi_c/libffi/testsuite/libffi.go/go.exp +36 -0
  456. data/ext/ffi_c/libffi/testsuite/libffi.go/static-chain.h +19 -0
  457. data/ext/ffi_c/rbffi.h +55 -0
  458. data/ext/ffi_c/rbffi_endian.h +59 -0
  459. data/ext/ffi_c/win32/stdbool.h +8 -0
  460. data/ext/ffi_c/win32/stdint.h +201 -0
  461. data/ffi.gemspec +43 -0
  462. data/lib/ffi.rb +20 -0
  463. data/lib/ffi/autopointer.rb +203 -0
  464. data/lib/ffi/buffer.rb +4 -0
  465. data/lib/ffi/callback.rb +4 -0
  466. data/lib/ffi/data_converter.rb +67 -0
  467. data/lib/ffi/enum.rb +296 -0
  468. data/lib/ffi/errno.rb +43 -0
  469. data/lib/ffi/ffi.rb +45 -0
  470. data/lib/ffi/io.rb +62 -0
  471. data/lib/ffi/library.rb +588 -0
  472. data/lib/ffi/managedstruct.rb +84 -0
  473. data/lib/ffi/memorypointer.rb +1 -0
  474. data/lib/ffi/platform.rb +175 -0
  475. data/lib/ffi/platform/aarch64-freebsd/types.conf +128 -0
  476. data/lib/ffi/platform/aarch64-freebsd12/types.conf +128 -0
  477. data/lib/ffi/platform/aarch64-linux/types.conf +104 -0
  478. data/lib/ffi/platform/arm-freebsd/types.conf +152 -0
  479. data/lib/ffi/platform/arm-freebsd12/types.conf +152 -0
  480. data/lib/ffi/platform/arm-linux/types.conf +104 -0
  481. data/lib/ffi/platform/i386-cygwin/types.conf +3 -0
  482. data/lib/ffi/platform/i386-darwin/types.conf +100 -0
  483. data/lib/ffi/platform/i386-freebsd/types.conf +152 -0
  484. data/lib/ffi/platform/i386-freebsd12/types.conf +152 -0
  485. data/lib/ffi/platform/i386-gnu/types.conf +107 -0
  486. data/lib/ffi/platform/i386-linux/types.conf +103 -0
  487. data/lib/ffi/platform/i386-netbsd/types.conf +126 -0
  488. data/lib/ffi/platform/i386-openbsd/types.conf +128 -0
  489. data/lib/ffi/platform/i386-solaris/types.conf +122 -0
  490. data/lib/ffi/platform/i386-windows/types.conf +105 -0
  491. data/lib/ffi/platform/ia64-linux/types.conf +104 -0
  492. data/lib/ffi/platform/mips-linux/types.conf +102 -0
  493. data/lib/ffi/platform/mips64-linux/types.conf +104 -0
  494. data/lib/ffi/platform/mips64el-linux/types.conf +104 -0
  495. data/lib/ffi/platform/mipsel-linux/types.conf +102 -0
  496. data/lib/ffi/platform/mipsisa32r6-linux/types.conf +102 -0
  497. data/lib/ffi/platform/mipsisa32r6el-linux/types.conf +102 -0
  498. data/lib/ffi/platform/mipsisa64r6-linux/types.conf +104 -0
  499. data/lib/ffi/platform/mipsisa64r6el-linux/types.conf +104 -0
  500. data/lib/ffi/platform/powerpc-aix/types.conf +180 -0
  501. data/lib/ffi/platform/powerpc-darwin/types.conf +100 -0
  502. data/lib/ffi/platform/powerpc-linux/types.conf +100 -0
  503. data/lib/ffi/platform/powerpc64-linux/types.conf +104 -0
  504. data/lib/ffi/platform/s390-linux/types.conf +102 -0
  505. data/lib/ffi/platform/s390x-linux/types.conf +102 -0
  506. data/lib/ffi/platform/sparc-linux/types.conf +102 -0
  507. data/lib/ffi/platform/sparc-solaris/types.conf +128 -0
  508. data/lib/ffi/platform/sparc64-linux/types.conf +102 -0
  509. data/lib/ffi/platform/sparcv9-solaris/types.conf +128 -0
  510. data/lib/ffi/platform/x86_64-cygwin/types.conf +3 -0
  511. data/lib/ffi/platform/x86_64-darwin/types.conf +126 -0
  512. data/lib/ffi/platform/x86_64-dragonflybsd/types.conf +148 -0
  513. data/lib/ffi/platform/x86_64-freebsd/types.conf +128 -0
  514. data/lib/ffi/platform/x86_64-freebsd12/types.conf +158 -0
  515. data/lib/ffi/platform/x86_64-linux/types.conf +111 -0
  516. data/lib/ffi/platform/x86_64-netbsd/types.conf +128 -0
  517. data/lib/ffi/platform/x86_64-openbsd/types.conf +134 -0
  518. data/lib/ffi/platform/x86_64-solaris/types.conf +122 -0
  519. data/lib/ffi/platform/x86_64-windows/types.conf +120 -0
  520. data/lib/ffi/pointer.rb +160 -0
  521. data/lib/ffi/struct.rb +311 -0
  522. data/lib/ffi/struct_by_reference.rb +72 -0
  523. data/lib/ffi/struct_layout.rb +96 -0
  524. data/lib/ffi/struct_layout_builder.rb +227 -0
  525. data/lib/ffi/tools/const_generator.rb +230 -0
  526. data/lib/ffi/tools/generator.rb +105 -0
  527. data/lib/ffi/tools/generator_task.rb +32 -0
  528. data/lib/ffi/tools/struct_generator.rb +194 -0
  529. data/lib/ffi/tools/types_generator.rb +135 -0
  530. data/lib/ffi/types.rb +194 -0
  531. data/lib/ffi/union.rb +43 -0
  532. data/lib/ffi/variadic.rb +78 -0
  533. data/lib/ffi/version.rb +3 -0
  534. data/samples/getlogin.rb +8 -0
  535. data/samples/getpid.rb +8 -0
  536. data/samples/gettimeofday.rb +18 -0
  537. data/samples/hello.rb +7 -0
  538. data/samples/inotify.rb +60 -0
  539. data/samples/pty.rb +76 -0
  540. data/samples/qsort.rb +21 -0
  541. data/samples/sample_helper.rb +6 -0
  542. metadata +677 -0
@@ -0,0 +1,43 @@
1
+ /* -----------------------------------------------------------------------
2
+ ffitarget.h - Copyright (c) 2012 Alexandre K. I. de Mendonca <alexandre.keunecke@gmail.com>
3
+
4
+ Blackfin Foreign Function Interface
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining
7
+ a copy of this software and associated documentation files (the
8
+ ``Software''), to deal in the Software without restriction, including
9
+ without limitation the rights to use, copy, modify, merge, publish,
10
+ distribute, sublicense, and/or sell copies of the Software, and to
11
+ permit persons to whom the Software is furnished to do so, subject to
12
+ the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be included
15
+ in all copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
18
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24
+ DEALINGS IN THE SOFTWARE.
25
+ ----------------------------------------------------------------------- */
26
+
27
+ #ifndef LIBFFI_TARGET_H
28
+ #define LIBFFI_TARGET_H
29
+
30
+ #ifndef LIBFFI_ASM
31
+ typedef unsigned long ffi_arg;
32
+ typedef signed long ffi_sarg;
33
+
34
+ typedef enum ffi_abi {
35
+ FFI_FIRST_ABI = 0,
36
+ FFI_SYSV,
37
+ FFI_LAST_ABI,
38
+ FFI_DEFAULT_ABI = FFI_SYSV
39
+ } ffi_abi;
40
+ #endif
41
+
42
+ #endif
43
+
@@ -0,0 +1,179 @@
1
+ /* -----------------------------------------------------------------------
2
+ sysv.S - Copyright (c) 2012 Alexandre K. I. de Mendonca <alexandre.keunecke@gmail.com>,
3
+ Paulo Pizarro <paulo.pizarro@gmail.com>
4
+
5
+ Blackfin Foreign Function Interface
6
+
7
+ Permission is hereby granted, free of charge, to any person obtaining
8
+ a copy of this software and associated documentation files (the
9
+ ``Software''), to deal in the Software without restriction, including
10
+ without limitation the rights to use, copy, modify, merge, publish,
11
+ distribute, sublicense, and/or sell copies of the Software, and to
12
+ permit persons to whom the Software is furnished to do so, subject to
13
+ the following conditions:
14
+
15
+ The above copyright notice and this permission notice shall be included
16
+ in all copies or substantial portions of the Software.
17
+
18
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
19
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25
+ DEALINGS IN THE SOFTWARE.
26
+ ----------------------------------------------------------------------- */
27
+
28
+ #define LIBFFI_ASM
29
+ #include <fficonfig.h>
30
+ #include <ffi.h>
31
+
32
+ .text
33
+ .align 4
34
+
35
+ /*
36
+ There is a "feature" in the bfin toolchain that it puts a _ before function names
37
+ that's why the function here it's called _ffi_call_SYSV and not ffi_call_SYSV
38
+ */
39
+ .global _ffi_call_SYSV;
40
+ .type _ffi_call_SYSV, STT_FUNC;
41
+ .func ffi_call_SYSV
42
+
43
+ /*
44
+ cif->bytes = R0 (fp+8)
45
+ &ecif = R1 (fp+12)
46
+ ffi_prep_args = R2 (fp+16)
47
+ ret_type = stack (fp+20)
48
+ ecif.rvalue = stack (fp+24)
49
+ fn = stack (fp+28)
50
+ got (fp+32)
51
+
52
+ There is room for improvement here (we can use temporary registers
53
+ instead of saving the values in the memory)
54
+ REGS:
55
+ P5 => Stack pointer (function arguments)
56
+ R5 => cif->bytes
57
+ R4 => ret->type
58
+
59
+ FP-20 = P3
60
+ FP-16 = SP (parameters area)
61
+ FP-12 = SP (temp)
62
+ FP-08 = function return part 1 [R0]
63
+ FP-04 = function return part 2 [R1]
64
+ */
65
+
66
+ _ffi_call_SYSV:
67
+ .prologue:
68
+ LINK 20;
69
+ [FP-20] = P3;
70
+ [FP+8] = R0;
71
+ [FP+12] = R1;
72
+ [FP+16] = R2;
73
+
74
+ .allocate_stack:
75
+ //alocate cif->bytes into the stack
76
+ R1 = [FP+8];
77
+ R0 = SP;
78
+ R0 = R0 - R1;
79
+ R1 = 4;
80
+ R0 = R0 - R1;
81
+ [FP-12] = SP;
82
+ SP = R0;
83
+ [FP-16] = SP;
84
+
85
+ .call_prep_args:
86
+ //get the addr of prep_args
87
+ P0 = [P3 + _ffi_prep_args@FUNCDESC_GOT17M4];
88
+ P1 = [P0];
89
+ P3 = [P0+4];
90
+ R0 = [FP-16];//SP (parameter area)
91
+ R1 = [FP+12];//ecif
92
+ call (P1);
93
+
94
+ .call_user_function:
95
+ //ajust SP so as to allow the user function access the parameters on the stack
96
+ SP = [FP-16]; //point to function parameters
97
+ R0 = [SP];
98
+ R1 = [SP+4];
99
+ R2 = [SP+8];
100
+ //load user function address
101
+ P0 = FP;
102
+ P0 +=28;
103
+ P1 = [P0];
104
+ P1 = [P1];
105
+ P3 = [P0+4];
106
+ /*
107
+ For functions returning aggregate values (struct) occupying more than 8 bytes,
108
+ the caller allocates the return value object on the stack and the address
109
+ of this object is passed to the callee as a hidden argument in register P0.
110
+ */
111
+ P0 = [FP+24];
112
+
113
+ call (P1);
114
+ SP = [FP-12];
115
+ .compute_return:
116
+ P2 = [FP-20];
117
+ [FP-8] = R0;
118
+ [FP-4] = R1;
119
+
120
+ R0 = [FP+20];
121
+ R1 = R0 << 2;
122
+
123
+ R0 = [P2+.rettable@GOT17M4];
124
+ R0 = R1 + R0;
125
+ P2 = R0;
126
+ R1 = [P2];
127
+
128
+ P2 = [FP+-20];
129
+ R0 = [P2+.rettable@GOT17M4];
130
+ R0 = R1 + R0;
131
+ P2 = R0;
132
+ R0 = [FP-8];
133
+ R1 = [FP-4];
134
+ jump (P2);
135
+
136
+ /*
137
+ #define FFIBFIN_RET_VOID 0
138
+ #define FFIBFIN_RET_BYTE 1
139
+ #define FFIBFIN_RET_HALFWORD 2
140
+ #define FFIBFIN_RET_INT64 3
141
+ #define FFIBFIN_RET_INT32 4
142
+ */
143
+ .align 4
144
+ .align 4
145
+ .rettable:
146
+ .dd .epilogue - .rettable
147
+ .dd .rbyte - .rettable;
148
+ .dd .rhalfword - .rettable;
149
+ .dd .rint64 - .rettable;
150
+ .dd .rint32 - .rettable;
151
+
152
+ .rbyte:
153
+ P0 = [FP+24];
154
+ R0 = R0.B (Z);
155
+ [P0] = R0;
156
+ JUMP .epilogue
157
+ .rhalfword:
158
+ P0 = [FP+24];
159
+ R0 = R0.L;
160
+ [P0] = R0;
161
+ JUMP .epilogue
162
+ .rint64:
163
+ P0 = [FP+24];// &rvalue
164
+ [P0] = R0;
165
+ [P0+4] = R1;
166
+ JUMP .epilogue
167
+ .rint32:
168
+ P0 = [FP+24];
169
+ [P0] = R0;
170
+ .epilogue:
171
+ R0 = [FP+8];
172
+ R1 = [FP+12];
173
+ R2 = [FP+16];
174
+ P3 = [FP-20];
175
+ UNLINK;
176
+ RTS;
177
+
178
+ .size _ffi_call_SYSV,.-_ffi_call_SYSV;
179
+ .endfunc
@@ -0,0 +1,990 @@
1
+ /* -----------------------------------------------------------------------
2
+ closures.c - Copyright (c) 2007, 2009, 2010 Red Hat, Inc.
3
+ Copyright (C) 2007, 2009, 2010 Free Software Foundation, Inc
4
+ Copyright (c) 2011 Plausible Labs Cooperative, Inc.
5
+
6
+ Code to allocate and deallocate memory for closures.
7
+
8
+ Permission is hereby granted, free of charge, to any person obtaining
9
+ a copy of this software and associated documentation files (the
10
+ ``Software''), to deal in the Software without restriction, including
11
+ without limitation the rights to use, copy, modify, merge, publish,
12
+ distribute, sublicense, and/or sell copies of the Software, and to
13
+ permit persons to whom the Software is furnished to do so, subject to
14
+ the following conditions:
15
+
16
+ The above copyright notice and this permission notice shall be included
17
+ in all copies or substantial portions of the Software.
18
+
19
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
20
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
23
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26
+ DEALINGS IN THE SOFTWARE.
27
+ ----------------------------------------------------------------------- */
28
+
29
+ #if defined __linux__ && !defined _GNU_SOURCE
30
+ #define _GNU_SOURCE 1
31
+ #endif
32
+
33
+ #include <fficonfig.h>
34
+ #include <ffi.h>
35
+ #include <ffi_common.h>
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
+
113
+ #if !FFI_MMAP_EXEC_WRIT && !FFI_EXEC_TRAMPOLINE_TABLE
114
+ # if __linux__ && !defined(__ANDROID__)
115
+ /* This macro indicates it may be forbidden to map anonymous memory
116
+ with both write and execute permission. Code compiled when this
117
+ option is defined will attempt to map such pages once, but if it
118
+ fails, it falls back to creating a temporary file in a writable and
119
+ executable filesystem and mapping pages from it into separate
120
+ locations in the virtual memory space, one location writable and
121
+ another executable. */
122
+ # define FFI_MMAP_EXEC_WRIT 1
123
+ # define HAVE_MNTENT 1
124
+ # endif
125
+ # if defined(X86_WIN32) || defined(X86_WIN64) || defined(_M_ARM64) || defined(__OS2__)
126
+ /* Windows systems may have Data Execution Protection (DEP) enabled,
127
+ which requires the use of VirtualMalloc/VirtualFree to alloc/free
128
+ executable memory. */
129
+ # define FFI_MMAP_EXEC_WRIT 1
130
+ # endif
131
+ #endif
132
+
133
+ #if FFI_MMAP_EXEC_WRIT && !defined FFI_MMAP_EXEC_SELINUX
134
+ # if defined(__linux__) && !defined(__ANDROID__)
135
+ /* When defined to 1 check for SELinux and if SELinux is active,
136
+ don't attempt PROT_EXEC|PROT_WRITE mapping at all, as that
137
+ might cause audit messages. */
138
+ # define FFI_MMAP_EXEC_SELINUX 1
139
+ # endif
140
+ #endif
141
+
142
+ #if FFI_CLOSURES
143
+
144
+ #if FFI_EXEC_TRAMPOLINE_TABLE
145
+
146
+ #ifdef __MACH__
147
+
148
+ #include <mach/mach.h>
149
+ #include <pthread.h>
150
+ #include <stdio.h>
151
+ #include <stdlib.h>
152
+
153
+ extern void *ffi_closure_trampoline_table_page;
154
+
155
+ typedef struct ffi_trampoline_table ffi_trampoline_table;
156
+ typedef struct ffi_trampoline_table_entry ffi_trampoline_table_entry;
157
+
158
+ struct ffi_trampoline_table
159
+ {
160
+ /* contiguous writable and executable pages */
161
+ vm_address_t config_page;
162
+ vm_address_t trampoline_page;
163
+
164
+ /* free list tracking */
165
+ uint16_t free_count;
166
+ ffi_trampoline_table_entry *free_list;
167
+ ffi_trampoline_table_entry *free_list_pool;
168
+
169
+ ffi_trampoline_table *prev;
170
+ ffi_trampoline_table *next;
171
+ };
172
+
173
+ struct ffi_trampoline_table_entry
174
+ {
175
+ void *(*trampoline) (void);
176
+ ffi_trampoline_table_entry *next;
177
+ };
178
+
179
+ /* Total number of trampolines that fit in one trampoline table */
180
+ #define FFI_TRAMPOLINE_COUNT (PAGE_MAX_SIZE / FFI_TRAMPOLINE_SIZE)
181
+
182
+ static pthread_mutex_t ffi_trampoline_lock = PTHREAD_MUTEX_INITIALIZER;
183
+ static ffi_trampoline_table *ffi_trampoline_tables = NULL;
184
+
185
+ static ffi_trampoline_table *
186
+ ffi_trampoline_table_alloc (void)
187
+ {
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;
203
+
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)
215
+ {
216
+ vm_deallocate (mach_task_self (), config_page, PAGE_MAX_SIZE * 2);
217
+ return NULL;
218
+ }
219
+
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;
225
+
226
+ /* Create and initialize the free list */
227
+ table->free_list_pool =
228
+ calloc (FFI_TRAMPOLINE_COUNT, sizeof (ffi_trampoline_table_entry));
229
+
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));
235
+
236
+ if (i < table->free_count - 1)
237
+ entry->next = &table->free_list_pool[i + 1];
238
+ }
239
+
240
+ table->free_list = table->free_list_pool;
241
+
242
+ return table;
243
+ }
244
+
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;
251
+
252
+ if (table->next != NULL)
253
+ table->next->prev = table->prev;
254
+
255
+ /* Deallocate pages */
256
+ vm_deallocate (mach_task_self (), table->config_page, PAGE_MAX_SIZE * 2);
257
+
258
+ /* Deallocate free list */
259
+ free (table->free_list_pool);
260
+ free (table);
261
+ }
262
+
263
+ void *
264
+ ffi_closure_alloc (size_t size, void **code)
265
+ {
266
+ /* Create the closure */
267
+ ffi_closure *closure = malloc (size);
268
+ if (closure == NULL)
269
+ return NULL;
270
+
271
+ pthread_mutex_lock (&ffi_trampoline_lock);
272
+
273
+ /* Check for an active trampoline table with available entries. */
274
+ ffi_trampoline_table *table = ffi_trampoline_tables;
275
+ if (table == NULL || table->free_list == NULL)
276
+ {
277
+ table = ffi_trampoline_table_alloc ();
278
+ if (table == NULL)
279
+ {
280
+ pthread_mutex_unlock (&ffi_trampoline_lock);
281
+ free (closure);
282
+ return NULL;
283
+ }
284
+
285
+ /* Insert the new table at the top of the list */
286
+ table->next = ffi_trampoline_tables;
287
+ if (table->next != NULL)
288
+ table->next->prev = table;
289
+
290
+ ffi_trampoline_tables = table;
291
+ }
292
+
293
+ /* Claim the free entry */
294
+ ffi_trampoline_table_entry *entry = ffi_trampoline_tables->free_list;
295
+ ffi_trampoline_tables->free_list = entry->next;
296
+ ffi_trampoline_tables->free_count--;
297
+ entry->next = NULL;
298
+
299
+ pthread_mutex_unlock (&ffi_trampoline_lock);
300
+
301
+ /* Initialize the return values */
302
+ *code = entry->trampoline;
303
+ closure->trampoline_table = table;
304
+ closure->trampoline_table_entry = entry;
305
+
306
+ return closure;
307
+ }
308
+
309
+ void
310
+ ffi_closure_free (void *ptr)
311
+ {
312
+ ffi_closure *closure = ptr;
313
+
314
+ pthread_mutex_lock (&ffi_trampoline_lock);
315
+
316
+ /* Fetch the table and entry references */
317
+ ffi_trampoline_table *table = closure->trampoline_table;
318
+ ffi_trampoline_table_entry *entry = closure->trampoline_table_entry;
319
+
320
+ /* Return the entry to the free list */
321
+ entry->next = table->free_list;
322
+ table->free_list = entry;
323
+ table->free_count++;
324
+
325
+ /* If all trampolines within this table are free, and at least one other table exists, deallocate
326
+ * the table */
327
+ if (table->free_count == FFI_TRAMPOLINE_COUNT
328
+ && ffi_trampoline_tables != table)
329
+ {
330
+ ffi_trampoline_table_free (table);
331
+ }
332
+ else if (ffi_trampoline_tables != table)
333
+ {
334
+ /* Otherwise, bump this table to the top of the list */
335
+ table->prev = NULL;
336
+ table->next = ffi_trampoline_tables;
337
+ if (ffi_trampoline_tables != NULL)
338
+ ffi_trampoline_tables->prev = table;
339
+
340
+ ffi_trampoline_tables = table;
341
+ }
342
+
343
+ pthread_mutex_unlock (&ffi_trampoline_lock);
344
+
345
+ /* Free the closure */
346
+ free (closure);
347
+ }
348
+
349
+ #endif
350
+
351
+ // Per-target implementation; It's unclear what can reasonable be shared between two OS/architecture implementations.
352
+
353
+ #elif FFI_MMAP_EXEC_WRIT /* !FFI_EXEC_TRAMPOLINE_TABLE */
354
+
355
+ #define USE_LOCKS 1
356
+ #define USE_DL_PREFIX 1
357
+ #ifdef __GNUC__
358
+ #ifndef USE_BUILTIN_FFS
359
+ #define USE_BUILTIN_FFS 1
360
+ #endif
361
+ #endif
362
+
363
+ /* We need to use mmap, not sbrk. */
364
+ #define HAVE_MORECORE 0
365
+
366
+ /* We could, in theory, support mremap, but it wouldn't buy us anything. */
367
+ #define HAVE_MREMAP 0
368
+
369
+ /* We have no use for this, so save some code and data. */
370
+ #define NO_MALLINFO 1
371
+
372
+ /* We need all allocations to be in regular segments, otherwise we
373
+ lose track of the corresponding code address. */
374
+ #define DEFAULT_MMAP_THRESHOLD MAX_SIZE_T
375
+
376
+ /* Don't allocate more than a page unless needed. */
377
+ #define DEFAULT_GRANULARITY ((size_t)malloc_getpagesize)
378
+
379
+ #include <sys/types.h>
380
+ #include <sys/stat.h>
381
+ #include <fcntl.h>
382
+ #include <errno.h>
383
+ #ifndef _MSC_VER
384
+ #include <unistd.h>
385
+ #endif
386
+ #include <string.h>
387
+ #include <stdio.h>
388
+ #if !defined(X86_WIN32) && !defined(X86_WIN64) && !defined(_M_ARM64)
389
+ #ifdef HAVE_MNTENT
390
+ #include <mntent.h>
391
+ #endif /* HAVE_MNTENT */
392
+ #include <sys/param.h>
393
+ #include <pthread.h>
394
+
395
+ /* We don't want sys/mman.h to be included after we redefine mmap and
396
+ dlmunmap. */
397
+ #include <sys/mman.h>
398
+ #define LACKS_SYS_MMAN_H 1
399
+
400
+ #if FFI_MMAP_EXEC_SELINUX
401
+ #include <sys/statfs.h>
402
+ #include <stdlib.h>
403
+
404
+ static int selinux_enabled = -1;
405
+
406
+ static int
407
+ selinux_enabled_check (void)
408
+ {
409
+ struct statfs sfs;
410
+ FILE *f;
411
+ char *buf = NULL;
412
+ size_t len = 0;
413
+
414
+ if (statfs ("/selinux", &sfs) >= 0
415
+ && (unsigned int) sfs.f_type == 0xf97cff8cU)
416
+ return 1;
417
+ f = fopen ("/proc/mounts", "r");
418
+ if (f == NULL)
419
+ return 0;
420
+ while (getline (&buf, &len, f) >= 0)
421
+ {
422
+ char *p = strchr (buf, ' ');
423
+ if (p == NULL)
424
+ break;
425
+ p = strchr (p + 1, ' ');
426
+ if (p == NULL)
427
+ break;
428
+ if (strncmp (p + 1, "selinuxfs ", 10) == 0)
429
+ {
430
+ free (buf);
431
+ fclose (f);
432
+ return 1;
433
+ }
434
+ }
435
+ free (buf);
436
+ fclose (f);
437
+ return 0;
438
+ }
439
+
440
+ #define is_selinux_enabled() (selinux_enabled >= 0 ? selinux_enabled \
441
+ : (selinux_enabled = selinux_enabled_check ()))
442
+
443
+ #else
444
+
445
+ #define is_selinux_enabled() 0
446
+
447
+ #endif /* !FFI_MMAP_EXEC_SELINUX */
448
+
449
+ /* On PaX enable kernels that have MPROTECT enable we can't use PROT_EXEC. */
450
+ #ifdef FFI_MMAP_EXEC_EMUTRAMP_PAX
451
+ #include <stdlib.h>
452
+
453
+ static int emutramp_enabled = -1;
454
+
455
+ static int
456
+ emutramp_enabled_check (void)
457
+ {
458
+ char *buf = NULL;
459
+ size_t len = 0;
460
+ FILE *f;
461
+ int ret;
462
+ f = fopen ("/proc/self/status", "r");
463
+ if (f == NULL)
464
+ return 0;
465
+ ret = 0;
466
+
467
+ while (getline (&buf, &len, f) != -1)
468
+ if (!strncmp (buf, "PaX:", 4))
469
+ {
470
+ char emutramp;
471
+ if (sscanf (buf, "%*s %*c%c", &emutramp) == 1)
472
+ ret = (emutramp == 'E');
473
+ break;
474
+ }
475
+ free (buf);
476
+ fclose (f);
477
+ return ret;
478
+ }
479
+
480
+ #define is_emutramp_enabled() (emutramp_enabled >= 0 ? emutramp_enabled \
481
+ : (emutramp_enabled = emutramp_enabled_check ()))
482
+ #endif /* FFI_MMAP_EXEC_EMUTRAMP_PAX */
483
+
484
+ #elif defined (__CYGWIN__) || defined(__INTERIX)
485
+
486
+ #include <sys/mman.h>
487
+
488
+ /* Cygwin is Linux-like, but not quite that Linux-like. */
489
+ #define is_selinux_enabled() 0
490
+
491
+ #endif /* !defined(X86_WIN32) && !defined(X86_WIN64) */
492
+
493
+ #ifndef FFI_MMAP_EXEC_EMUTRAMP_PAX
494
+ #define is_emutramp_enabled() 0
495
+ #endif /* FFI_MMAP_EXEC_EMUTRAMP_PAX */
496
+
497
+ /* Declare all functions defined in dlmalloc.c as static. */
498
+ static void *dlmalloc(size_t);
499
+ static void dlfree(void*);
500
+ static void *dlcalloc(size_t, size_t) MAYBE_UNUSED;
501
+ static void *dlrealloc(void *, size_t) MAYBE_UNUSED;
502
+ static void *dlmemalign(size_t, size_t) MAYBE_UNUSED;
503
+ static void *dlvalloc(size_t) MAYBE_UNUSED;
504
+ static int dlmallopt(int, int) MAYBE_UNUSED;
505
+ static size_t dlmalloc_footprint(void) MAYBE_UNUSED;
506
+ static size_t dlmalloc_max_footprint(void) MAYBE_UNUSED;
507
+ static void** dlindependent_calloc(size_t, size_t, void**) MAYBE_UNUSED;
508
+ static void** dlindependent_comalloc(size_t, size_t*, void**) MAYBE_UNUSED;
509
+ static void *dlpvalloc(size_t) MAYBE_UNUSED;
510
+ static int dlmalloc_trim(size_t) MAYBE_UNUSED;
511
+ static size_t dlmalloc_usable_size(void*) MAYBE_UNUSED;
512
+ static void dlmalloc_stats(void) MAYBE_UNUSED;
513
+
514
+ #if !(defined(X86_WIN32) || defined(X86_WIN64) || defined(_M_ARM64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX)
515
+ /* Use these for mmap and munmap within dlmalloc.c. */
516
+ static void *dlmmap(void *, size_t, int, int, int, off_t);
517
+ static int dlmunmap(void *, size_t);
518
+ #endif /* !(defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX) */
519
+
520
+ #define mmap dlmmap
521
+ #define munmap dlmunmap
522
+
523
+ #include "dlmalloc.c"
524
+
525
+ #undef mmap
526
+ #undef munmap
527
+
528
+ #if !(defined(X86_WIN32) || defined(X86_WIN64) || defined(_M_ARM64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX)
529
+
530
+ /* A mutex used to synchronize access to *exec* variables in this file. */
531
+ static pthread_mutex_t open_temp_exec_file_mutex = PTHREAD_MUTEX_INITIALIZER;
532
+
533
+ /* A file descriptor of a temporary file from which we'll map
534
+ executable pages. */
535
+ static int execfd = -1;
536
+
537
+ /* The amount of space already allocated from the temporary file. */
538
+ static size_t execsize = 0;
539
+
540
+ /* Open a temporary file name, and immediately unlink it. */
541
+ static int
542
+ open_temp_exec_file_name (char *name, int flags)
543
+ {
544
+ int fd;
545
+
546
+ #ifdef HAVE_MKOSTEMP
547
+ fd = mkostemp (name, flags);
548
+ #else
549
+ fd = mkstemp (name);
550
+ #endif
551
+
552
+ if (fd != -1)
553
+ unlink (name);
554
+
555
+ return fd;
556
+ }
557
+
558
+ /* Open a temporary file in the named directory. */
559
+ static int
560
+ open_temp_exec_file_dir (const char *dir)
561
+ {
562
+ static const char suffix[] = "/ffiXXXXXX";
563
+ int lendir, flags;
564
+ char *tempname;
565
+ #ifdef O_TMPFILE
566
+ int fd;
567
+ #endif
568
+
569
+ #ifdef O_CLOEXEC
570
+ flags = O_CLOEXEC;
571
+ #else
572
+ flags = 0;
573
+ #endif
574
+
575
+ #ifdef O_TMPFILE
576
+ fd = open (dir, flags | O_RDWR | O_EXCL | O_TMPFILE, 0700);
577
+ /* If the running system does not support the O_TMPFILE flag then retry without it. */
578
+ if (fd != -1 || (errno != EINVAL && errno != EISDIR && errno != EOPNOTSUPP)) {
579
+ return fd;
580
+ } else {
581
+ errno = 0;
582
+ }
583
+ #endif
584
+
585
+ lendir = (int) strlen (dir);
586
+ tempname = __builtin_alloca (lendir + sizeof (suffix));
587
+
588
+ if (!tempname)
589
+ return -1;
590
+
591
+ memcpy (tempname, dir, lendir);
592
+ memcpy (tempname + lendir, suffix, sizeof (suffix));
593
+
594
+ return open_temp_exec_file_name (tempname, flags);
595
+ }
596
+
597
+ /* Open a temporary file in the directory in the named environment
598
+ variable. */
599
+ static int
600
+ open_temp_exec_file_env (const char *envvar)
601
+ {
602
+ const char *value = getenv (envvar);
603
+
604
+ if (!value)
605
+ return -1;
606
+
607
+ return open_temp_exec_file_dir (value);
608
+ }
609
+
610
+ #ifdef HAVE_MNTENT
611
+ /* Open a temporary file in an executable and writable mount point
612
+ listed in the mounts file. Subsequent calls with the same mounts
613
+ keep searching for mount points in the same file. Providing NULL
614
+ as the mounts file closes the file. */
615
+ static int
616
+ open_temp_exec_file_mnt (const char *mounts)
617
+ {
618
+ static const char *last_mounts;
619
+ static FILE *last_mntent;
620
+
621
+ if (mounts != last_mounts)
622
+ {
623
+ if (last_mntent)
624
+ endmntent (last_mntent);
625
+
626
+ last_mounts = mounts;
627
+
628
+ if (mounts)
629
+ last_mntent = setmntent (mounts, "r");
630
+ else
631
+ last_mntent = NULL;
632
+ }
633
+
634
+ if (!last_mntent)
635
+ return -1;
636
+
637
+ for (;;)
638
+ {
639
+ int fd;
640
+ struct mntent mnt;
641
+ char buf[MAXPATHLEN * 3];
642
+
643
+ if (getmntent_r (last_mntent, &mnt, buf, sizeof (buf)) == NULL)
644
+ return -1;
645
+
646
+ if (hasmntopt (&mnt, "ro")
647
+ || hasmntopt (&mnt, "noexec")
648
+ || access (mnt.mnt_dir, W_OK))
649
+ continue;
650
+
651
+ fd = open_temp_exec_file_dir (mnt.mnt_dir);
652
+
653
+ if (fd != -1)
654
+ return fd;
655
+ }
656
+ }
657
+ #endif /* HAVE_MNTENT */
658
+
659
+ /* Instructions to look for a location to hold a temporary file that
660
+ can be mapped in for execution. */
661
+ static struct
662
+ {
663
+ int (*func)(const char *);
664
+ const char *arg;
665
+ int repeat;
666
+ } open_temp_exec_file_opts[] = {
667
+ { open_temp_exec_file_env, "TMPDIR", 0 },
668
+ { open_temp_exec_file_dir, "/tmp", 0 },
669
+ { open_temp_exec_file_dir, "/var/tmp", 0 },
670
+ { open_temp_exec_file_dir, "/dev/shm", 0 },
671
+ { open_temp_exec_file_env, "HOME", 0 },
672
+ #ifdef HAVE_MNTENT
673
+ { open_temp_exec_file_mnt, "/etc/mtab", 1 },
674
+ { open_temp_exec_file_mnt, "/proc/mounts", 1 },
675
+ #endif /* HAVE_MNTENT */
676
+ };
677
+
678
+ /* Current index into open_temp_exec_file_opts. */
679
+ static int open_temp_exec_file_opts_idx = 0;
680
+
681
+ /* Reset a current multi-call func, then advances to the next entry.
682
+ If we're at the last, go back to the first and return nonzero,
683
+ otherwise return zero. */
684
+ static int
685
+ open_temp_exec_file_opts_next (void)
686
+ {
687
+ if (open_temp_exec_file_opts[open_temp_exec_file_opts_idx].repeat)
688
+ open_temp_exec_file_opts[open_temp_exec_file_opts_idx].func (NULL);
689
+
690
+ open_temp_exec_file_opts_idx++;
691
+ if (open_temp_exec_file_opts_idx
692
+ == (sizeof (open_temp_exec_file_opts)
693
+ / sizeof (*open_temp_exec_file_opts)))
694
+ {
695
+ open_temp_exec_file_opts_idx = 0;
696
+ return 1;
697
+ }
698
+
699
+ return 0;
700
+ }
701
+
702
+ /* Return a file descriptor of a temporary zero-sized file in a
703
+ writable and executable filesystem. */
704
+ static int
705
+ open_temp_exec_file (void)
706
+ {
707
+ int fd;
708
+
709
+ do
710
+ {
711
+ fd = open_temp_exec_file_opts[open_temp_exec_file_opts_idx].func
712
+ (open_temp_exec_file_opts[open_temp_exec_file_opts_idx].arg);
713
+
714
+ if (!open_temp_exec_file_opts[open_temp_exec_file_opts_idx].repeat
715
+ || fd == -1)
716
+ {
717
+ if (open_temp_exec_file_opts_next ())
718
+ break;
719
+ }
720
+ }
721
+ while (fd == -1);
722
+
723
+ return fd;
724
+ }
725
+
726
+ /* We need to allocate space in a file that will be backing a writable
727
+ mapping. Several problems exist with the usual approaches:
728
+ - fallocate() is Linux-only
729
+ - posix_fallocate() is not available on all platforms
730
+ - ftruncate() does not allocate space on filesystems with sparse files
731
+ Failure to allocate the space will cause SIGBUS to be thrown when
732
+ the mapping is subsequently written to. */
733
+ static int
734
+ allocate_space (int fd, off_t offset, off_t len)
735
+ {
736
+ static size_t page_size;
737
+
738
+ /* Obtain system page size. */
739
+ if (!page_size)
740
+ page_size = sysconf(_SC_PAGESIZE);
741
+
742
+ unsigned char buf[page_size];
743
+ memset (buf, 0, page_size);
744
+
745
+ while (len > 0)
746
+ {
747
+ off_t to_write = (len < page_size) ? len : page_size;
748
+ if (write (fd, buf, to_write) < to_write)
749
+ return -1;
750
+ len -= to_write;
751
+ }
752
+
753
+ return 0;
754
+ }
755
+
756
+ /* Map in a chunk of memory from the temporary exec file into separate
757
+ locations in the virtual memory address space, one writable and one
758
+ executable. Returns the address of the writable portion, after
759
+ storing an offset to the corresponding executable portion at the
760
+ last word of the requested chunk. */
761
+ static void *
762
+ dlmmap_locked (void *start, size_t length, int prot, int flags, off_t offset)
763
+ {
764
+ void *ptr;
765
+
766
+ if (execfd == -1)
767
+ {
768
+ open_temp_exec_file_opts_idx = 0;
769
+ retry_open:
770
+ execfd = open_temp_exec_file ();
771
+ if (execfd == -1)
772
+ return MFAIL;
773
+ }
774
+
775
+ offset = execsize;
776
+
777
+ if (allocate_space (execfd, offset, length))
778
+ return MFAIL;
779
+
780
+ flags &= ~(MAP_PRIVATE | MAP_ANONYMOUS);
781
+ flags |= MAP_SHARED;
782
+
783
+ ptr = mmap (NULL, length, (prot & ~PROT_WRITE) | PROT_EXEC,
784
+ flags, execfd, offset);
785
+ if (ptr == MFAIL)
786
+ {
787
+ if (!offset)
788
+ {
789
+ close (execfd);
790
+ goto retry_open;
791
+ }
792
+ if (ftruncate (execfd, offset) != 0)
793
+ {
794
+ /* Fixme : Error logs can be added here. Returning an error for
795
+ * ftruncte() will not add any advantage as it is being
796
+ * validating in the error case. */
797
+ }
798
+
799
+ return MFAIL;
800
+ }
801
+ else if (!offset
802
+ && open_temp_exec_file_opts[open_temp_exec_file_opts_idx].repeat)
803
+ open_temp_exec_file_opts_next ();
804
+
805
+ start = mmap (start, length, prot, flags, execfd, offset);
806
+
807
+ if (start == MFAIL)
808
+ {
809
+ munmap (ptr, length);
810
+ if (ftruncate (execfd, offset) != 0)
811
+ {
812
+ /* Fixme : Error logs can be added here. Returning an error for
813
+ * ftruncte() will not add any advantage as it is being
814
+ * validating in the error case. */
815
+ }
816
+ return start;
817
+ }
818
+
819
+ mmap_exec_offset ((char *)start, length) = (char*)ptr - (char*)start;
820
+
821
+ execsize += length;
822
+
823
+ return start;
824
+ }
825
+
826
+ /* Map in a writable and executable chunk of memory if possible.
827
+ Failing that, fall back to dlmmap_locked. */
828
+ static void *
829
+ dlmmap (void *start, size_t length, int prot,
830
+ int flags, int fd, off_t offset)
831
+ {
832
+ void *ptr;
833
+
834
+ assert (start == NULL && length % malloc_getpagesize == 0
835
+ && prot == (PROT_READ | PROT_WRITE)
836
+ && flags == (MAP_PRIVATE | MAP_ANONYMOUS)
837
+ && fd == -1 && offset == 0);
838
+
839
+ if (execfd == -1 && is_emutramp_enabled ())
840
+ {
841
+ ptr = mmap (start, length, prot & ~PROT_EXEC, flags, fd, offset);
842
+ return ptr;
843
+ }
844
+
845
+ if (execfd == -1 && !is_selinux_enabled ())
846
+ {
847
+ ptr = mmap (start, length, prot | PROT_EXEC, flags, fd, offset);
848
+
849
+ if (ptr != MFAIL || (errno != EPERM && errno != EACCES))
850
+ /* Cool, no need to mess with separate segments. */
851
+ return ptr;
852
+
853
+ /* If MREMAP_DUP is ever introduced and implemented, try mmap
854
+ with ((prot & ~PROT_WRITE) | PROT_EXEC) and mremap with
855
+ MREMAP_DUP and prot at this point. */
856
+ }
857
+
858
+ if (execsize == 0 || execfd == -1)
859
+ {
860
+ pthread_mutex_lock (&open_temp_exec_file_mutex);
861
+ ptr = dlmmap_locked (start, length, prot, flags, offset);
862
+ pthread_mutex_unlock (&open_temp_exec_file_mutex);
863
+
864
+ return ptr;
865
+ }
866
+
867
+ return dlmmap_locked (start, length, prot, flags, offset);
868
+ }
869
+
870
+ /* Release memory at the given address, as well as the corresponding
871
+ executable page if it's separate. */
872
+ static int
873
+ dlmunmap (void *start, size_t length)
874
+ {
875
+ /* We don't bother decreasing execsize or truncating the file, since
876
+ we can't quite tell whether we're unmapping the end of the file.
877
+ We don't expect frequent deallocation anyway. If we did, we
878
+ could locate pages in the file by writing to the pages being
879
+ deallocated and checking that the file contents change.
880
+ Yuck. */
881
+ msegmentptr seg = segment_holding (gm, start);
882
+ void *code;
883
+
884
+ if (seg && (code = add_segment_exec_offset (start, seg)) != start)
885
+ {
886
+ int ret = munmap (code, length);
887
+ if (ret)
888
+ return ret;
889
+ }
890
+
891
+ return munmap (start, length);
892
+ }
893
+
894
+ #if FFI_CLOSURE_FREE_CODE
895
+ /* Return segment holding given code address. */
896
+ static msegmentptr
897
+ segment_holding_code (mstate m, char* addr)
898
+ {
899
+ msegmentptr sp = &m->seg;
900
+ for (;;) {
901
+ if (addr >= add_segment_exec_offset (sp->base, sp)
902
+ && addr < add_segment_exec_offset (sp->base, sp) + sp->size)
903
+ return sp;
904
+ if ((sp = sp->next) == 0)
905
+ return 0;
906
+ }
907
+ }
908
+ #endif
909
+
910
+ #endif /* !(defined(X86_WIN32) || defined(X86_WIN64) || defined(_M_ARM64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX) */
911
+
912
+ /* Allocate a chunk of memory with the given size. Returns a pointer
913
+ to the writable address, and sets *CODE to the executable
914
+ corresponding virtual address. */
915
+ void *
916
+ ffi_closure_alloc (size_t size, void **code)
917
+ {
918
+ void *ptr;
919
+
920
+ if (!code)
921
+ return NULL;
922
+
923
+ ptr = dlmalloc (size);
924
+
925
+ if (ptr)
926
+ {
927
+ msegmentptr seg = segment_holding (gm, ptr);
928
+
929
+ *code = add_segment_exec_offset (ptr, seg);
930
+ }
931
+
932
+ return ptr;
933
+ }
934
+
935
+ void *
936
+ ffi_data_to_code_pointer (void *data)
937
+ {
938
+ msegmentptr seg = segment_holding (gm, data);
939
+ return add_segment_exec_offset (data, seg);
940
+ }
941
+
942
+ /* Release a chunk of memory allocated with ffi_closure_alloc. If
943
+ FFI_CLOSURE_FREE_CODE is nonzero, the given address can be the
944
+ writable or the executable address given. Otherwise, only the
945
+ writable address can be provided here. */
946
+ void
947
+ ffi_closure_free (void *ptr)
948
+ {
949
+ #if FFI_CLOSURE_FREE_CODE
950
+ msegmentptr seg = segment_holding_code (gm, ptr);
951
+
952
+ if (seg)
953
+ ptr = sub_segment_exec_offset (ptr, seg);
954
+ #endif
955
+
956
+ dlfree (ptr);
957
+ }
958
+
959
+ # else /* ! FFI_MMAP_EXEC_WRIT */
960
+
961
+ /* On many systems, memory returned by malloc is writable and
962
+ executable, so just use it. */
963
+
964
+ #include <stdlib.h>
965
+
966
+ void *
967
+ ffi_closure_alloc (size_t size, void **code)
968
+ {
969
+ if (!code)
970
+ return NULL;
971
+
972
+ return *code = malloc (size);
973
+ }
974
+
975
+ void
976
+ ffi_closure_free (void *ptr)
977
+ {
978
+ free (ptr);
979
+ }
980
+
981
+ void *
982
+ ffi_data_to_code_pointer (void *data)
983
+ {
984
+ return data;
985
+ }
986
+
987
+ # endif /* ! FFI_MMAP_EXEC_WRIT */
988
+ #endif /* FFI_CLOSURES */
989
+
990
+ #endif /* NetBSD with PROT_MPROTECT */