ffi 1.9.18 → 1.9.21

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of ffi might be problematic. Click here for more details.

Files changed (366) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -2
  3. data/Rakefile +14 -3
  4. data/ext/ffi_c/AbstractMemory.c +6 -1
  5. data/ext/ffi_c/Platform.c +10 -2
  6. data/ext/ffi_c/extconf.rb +7 -2
  7. data/ext/ffi_c/libffi.bsd.mk +9 -3
  8. data/ext/ffi_c/libffi.darwin.mk +14 -4
  9. data/ext/ffi_c/libffi.gnu.mk +2 -1
  10. data/ext/ffi_c/libffi.mk +9 -4
  11. data/ext/ffi_c/libffi/ChangeLog.libffi +2 -2
  12. data/ext/ffi_c/libffi/{ChangeLog → ChangeLog.libffi-3.1} +1402 -2
  13. data/ext/ffi_c/libffi/ChangeLog.v1 +1 -1
  14. data/ext/ffi_c/libffi/LICENSE +1 -1
  15. data/ext/ffi_c/libffi/Makefile.am +166 -157
  16. data/ext/ffi_c/libffi/README +164 -52
  17. data/ext/ffi_c/libffi/acinclude.m4 +381 -0
  18. data/ext/ffi_c/libffi/autogen.sh +2 -0
  19. data/ext/ffi_c/libffi/configure.ac +148 -256
  20. data/ext/ffi_c/libffi/configure.host +265 -4
  21. data/ext/ffi_c/libffi/doc/Makefile.am +3 -0
  22. data/ext/ffi_c/libffi/doc/libffi.texi +430 -45
  23. data/ext/ffi_c/libffi/doc/version.texi +4 -4
  24. data/ext/ffi_c/libffi/generate-darwin-source-and-headers.py +207 -0
  25. data/ext/ffi_c/libffi/include/Makefile.am +3 -3
  26. data/ext/ffi_c/libffi/include/ffi.h.in +107 -50
  27. data/ext/ffi_c/libffi/include/ffi_cfi.h +55 -0
  28. data/ext/ffi_c/libffi/include/ffi_common.h +32 -11
  29. data/ext/ffi_c/libffi/libffi.map.in +80 -0
  30. data/ext/ffi_c/libffi/libffi.pc.in +3 -2
  31. data/ext/ffi_c/libffi/libffi.xcodeproj/project.pbxproj +637 -0
  32. data/ext/ffi_c/libffi/libtool-ldflags +106 -0
  33. data/ext/ffi_c/libffi/libtool-version +1 -1
  34. data/ext/ffi_c/libffi/m4/asmcfi.m4 +13 -0
  35. data/ext/ffi_c/libffi/m4/ax_append_flag.m4 +69 -0
  36. data/ext/ffi_c/libffi/m4/ax_cc_maxopt.m4 +13 -8
  37. data/ext/ffi_c/libffi/m4/ax_cflags_warn_all.m4 +31 -104
  38. data/ext/ffi_c/libffi/m4/{ax_check_compiler_flags.m4 → ax_check_compile_flag.m4} +30 -34
  39. data/ext/ffi_c/libffi/m4/ax_compiler_vendor.m4 +32 -11
  40. data/ext/ffi_c/libffi/m4/ax_enable_builddir.m4 +6 -5
  41. data/ext/ffi_c/libffi/m4/ax_gcc_archflag.m4 +31 -21
  42. data/ext/ffi_c/libffi/man/Makefile.am +2 -2
  43. data/ext/ffi_c/libffi/man/ffi.3 +10 -0
  44. data/ext/ffi_c/libffi/man/ffi_prep_cif.3 +6 -4
  45. data/ext/ffi_c/libffi/man/ffi_prep_cif_var.3 +73 -0
  46. data/ext/ffi_c/libffi/msvcc.sh +72 -9
  47. data/ext/ffi_c/libffi/src/aarch64/ffi.c +941 -0
  48. data/ext/ffi_c/libffi/src/aarch64/ffitarget.h +81 -0
  49. data/ext/ffi_c/libffi/src/aarch64/internal.h +67 -0
  50. data/ext/ffi_c/libffi/src/aarch64/sysv.S +438 -0
  51. data/ext/ffi_c/libffi/src/alpha/ffi.c +335 -98
  52. data/ext/ffi_c/libffi/src/alpha/ffitarget.h +10 -1
  53. data/ext/ffi_c/libffi/src/alpha/internal.h +23 -0
  54. data/ext/ffi_c/libffi/src/alpha/osf.S +161 -266
  55. data/ext/ffi_c/libffi/src/arc/arcompact.S +135 -0
  56. data/ext/ffi_c/libffi/src/arc/ffi.c +266 -0
  57. data/ext/ffi_c/libffi/src/arc/ffitarget.h +53 -0
  58. data/ext/ffi_c/libffi/src/arm/ffi.c +597 -517
  59. data/ext/ffi_c/libffi/src/arm/ffitarget.h +24 -7
  60. data/ext/ffi_c/libffi/src/arm/internal.h +7 -0
  61. data/ext/ffi_c/libffi/src/arm/sysv.S +303 -417
  62. data/ext/ffi_c/libffi/src/avr32/ffitarget.h +6 -1
  63. data/ext/ffi_c/libffi/src/bfin/ffi.c +196 -0
  64. data/ext/ffi_c/libffi/src/bfin/ffitarget.h +43 -0
  65. data/ext/ffi_c/libffi/src/bfin/sysv.S +179 -0
  66. data/ext/ffi_c/libffi/src/closures.c +319 -44
  67. data/ext/ffi_c/libffi/src/cris/ffi.c +10 -7
  68. data/ext/ffi_c/libffi/src/cris/ffitarget.h +6 -1
  69. data/ext/ffi_c/libffi/src/debug.c +6 -1
  70. data/ext/ffi_c/libffi/src/dlmalloc.c +16 -11
  71. data/ext/ffi_c/libffi/src/frv/ffi.c +1 -1
  72. data/ext/ffi_c/libffi/src/frv/ffitarget.h +6 -1
  73. data/ext/ffi_c/libffi/src/ia64/ffi.c +11 -7
  74. data/ext/ffi_c/libffi/src/ia64/ffitarget.h +6 -1
  75. data/ext/ffi_c/libffi/src/java_raw_api.c +23 -5
  76. data/ext/ffi_c/libffi/src/m32r/ffi.c +1 -1
  77. data/ext/ffi_c/libffi/src/m32r/ffitarget.h +6 -1
  78. data/ext/ffi_c/libffi/src/m68k/ffi.c +87 -13
  79. data/ext/ffi_c/libffi/src/m68k/ffitarget.h +6 -1
  80. data/ext/ffi_c/libffi/src/m68k/sysv.S +119 -32
  81. data/ext/ffi_c/libffi/src/m88k/ffi.c +400 -0
  82. data/ext/ffi_c/libffi/src/m88k/ffitarget.h +49 -0
  83. data/ext/ffi_c/libffi/src/m88k/obsd.S +209 -0
  84. data/ext/ffi_c/libffi/src/metag/ffi.c +330 -0
  85. data/ext/ffi_c/libffi/{fficonfig.hw → src/metag/ffitarget.h} +22 -26
  86. data/ext/ffi_c/libffi/src/metag/sysv.S +311 -0
  87. data/ext/ffi_c/libffi/src/microblaze/ffi.c +321 -0
  88. data/ext/ffi_c/libffi/src/microblaze/ffitarget.h +53 -0
  89. data/ext/ffi_c/libffi/src/microblaze/sysv.S +302 -0
  90. data/ext/ffi_c/libffi/src/mips/ffi.c +95 -28
  91. data/ext/ffi_c/libffi/src/mips/ffitarget.h +9 -2
  92. data/ext/ffi_c/libffi/src/mips/n32.S +126 -56
  93. data/ext/ffi_c/libffi/src/mips/o32.S +148 -27
  94. data/ext/ffi_c/libffi/src/moxie/eabi.S +55 -82
  95. data/ext/ffi_c/libffi/src/moxie/ffi.c +40 -44
  96. data/ext/ffi_c/libffi/src/moxie/ffitarget.h +52 -0
  97. data/ext/ffi_c/libffi/src/nios2/ffi.c +304 -0
  98. data/ext/ffi_c/libffi/src/nios2/ffitarget.h +52 -0
  99. data/ext/ffi_c/libffi/src/nios2/sysv.S +136 -0
  100. data/ext/ffi_c/libffi/src/or1k/ffi.c +328 -0
  101. data/ext/ffi_c/libffi/src/or1k/ffitarget.h +58 -0
  102. data/ext/ffi_c/libffi/src/or1k/sysv.S +107 -0
  103. data/ext/ffi_c/libffi/src/pa/ffitarget.h +8 -1
  104. data/ext/ffi_c/libffi/src/powerpc/aix.S +6 -6
  105. data/ext/ffi_c/libffi/src/powerpc/aix_closure.S +3 -1
  106. data/ext/ffi_c/libffi/src/powerpc/asm.h +2 -2
  107. data/ext/ffi_c/libffi/src/powerpc/darwin.S +2 -7
  108. data/ext/ffi_c/libffi/src/powerpc/darwin_closure.S +22 -26
  109. data/ext/ffi_c/libffi/src/powerpc/ffi.c +103 -1378
  110. data/ext/ffi_c/libffi/src/powerpc/ffi_darwin.c +25 -25
  111. data/ext/ffi_c/libffi/src/powerpc/ffi_linux64.c +945 -0
  112. data/ext/ffi_c/libffi/src/powerpc/ffi_powerpc.h +94 -0
  113. data/ext/ffi_c/libffi/src/powerpc/ffi_sysv.c +923 -0
  114. data/ext/ffi_c/libffi/src/powerpc/ffitarget.h +100 -44
  115. data/ext/ffi_c/libffi/src/powerpc/linux64.S +100 -59
  116. data/ext/ffi_c/libffi/src/powerpc/linux64_closure.S +360 -108
  117. data/ext/ffi_c/libffi/src/powerpc/ppc_closure.S +138 -68
  118. data/ext/ffi_c/libffi/src/powerpc/sysv.S +68 -112
  119. data/ext/ffi_c/libffi/src/prep_cif.c +108 -24
  120. data/ext/ffi_c/libffi/src/raw_api.c +18 -5
  121. data/ext/ffi_c/libffi/src/s390/ffi.c +294 -318
  122. data/ext/ffi_c/libffi/src/s390/ffitarget.h +9 -1
  123. data/ext/ffi_c/libffi/src/s390/internal.h +11 -0
  124. data/ext/ffi_c/libffi/src/s390/sysv.S +257 -366
  125. data/ext/ffi_c/libffi/src/sh/ffi.c +4 -3
  126. data/ext/ffi_c/libffi/src/sh/ffitarget.h +6 -1
  127. data/ext/ffi_c/libffi/src/sh64/ffi.c +3 -2
  128. data/ext/ffi_c/libffi/src/sh64/ffitarget.h +6 -1
  129. data/ext/ffi_c/libffi/src/sparc/ffi.c +326 -527
  130. data/ext/ffi_c/libffi/src/sparc/ffi64.c +608 -0
  131. data/ext/ffi_c/libffi/src/sparc/ffitarget.h +20 -7
  132. data/ext/ffi_c/libffi/src/sparc/internal.h +26 -0
  133. data/ext/ffi_c/libffi/src/sparc/v8.S +364 -234
  134. data/ext/ffi_c/libffi/src/sparc/v9.S +340 -207
  135. data/ext/ffi_c/libffi/src/tile/ffi.c +355 -0
  136. data/ext/ffi_c/libffi/src/tile/ffitarget.h +65 -0
  137. data/ext/ffi_c/libffi/src/tile/tile.S +360 -0
  138. data/ext/ffi_c/libffi/src/types.c +43 -14
  139. data/ext/ffi_c/libffi/src/vax/elfbsd.S +195 -0
  140. data/ext/ffi_c/libffi/src/vax/ffi.c +276 -0
  141. data/ext/ffi_c/libffi/src/vax/ffitarget.h +49 -0
  142. data/ext/ffi_c/libffi/src/x86/asmnames.h +30 -0
  143. data/ext/ffi_c/libffi/src/x86/ffi.c +589 -500
  144. data/ext/ffi_c/libffi/src/x86/ffi64.c +338 -116
  145. data/ext/ffi_c/libffi/src/x86/ffitarget.h +55 -35
  146. data/ext/ffi_c/libffi/src/x86/ffiw64.c +287 -0
  147. data/ext/ffi_c/libffi/src/x86/internal.h +29 -0
  148. data/ext/ffi_c/libffi/src/x86/internal64.h +22 -0
  149. data/ext/ffi_c/libffi/src/x86/sysv.S +975 -400
  150. data/ext/ffi_c/libffi/src/x86/unix64.S +398 -299
  151. data/ext/ffi_c/libffi/src/x86/win64.S +222 -458
  152. data/ext/ffi_c/libffi/src/x86/win64_intel.S +237 -0
  153. data/ext/ffi_c/libffi/src/xtensa/ffi.c +298 -0
  154. data/ext/ffi_c/libffi/src/xtensa/ffitarget.h +53 -0
  155. data/ext/ffi_c/libffi/src/xtensa/sysv.S +253 -0
  156. data/ext/ffi_c/libffi/stamp-h.in +1 -0
  157. data/ext/ffi_c/libffi/testsuite/Makefile.am +78 -73
  158. data/ext/ffi_c/libffi/testsuite/lib/libffi.exp +120 -25
  159. data/ext/ffi_c/libffi/testsuite/lib/target-libpath.exp +21 -1
  160. data/ext/ffi_c/libffi/testsuite/libffi.call/align_mixed.c +46 -0
  161. data/ext/ffi_c/libffi/testsuite/libffi.call/call.exp +4 -6
  162. data/ext/ffi_c/libffi/testsuite/libffi.call/{closure_stdcall.c → closure_simple.c} +7 -16
  163. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_12byte.c +4 -4
  164. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_16byte.c +4 -4
  165. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_18byte.c +4 -4
  166. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_19byte.c +4 -4
  167. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_1_1byte.c +4 -4
  168. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_20byte.c +4 -4
  169. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_20byte1.c +4 -4
  170. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_24byte.c +5 -5
  171. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_2byte.c +4 -4
  172. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3_1byte.c +4 -4
  173. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3byte1.c +4 -4
  174. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3byte2.c +4 -4
  175. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_4_1byte.c +4 -4
  176. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_4byte.c +4 -4
  177. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_5_1_byte.c +4 -4
  178. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_5byte.c +4 -4
  179. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_64byte.c +5 -5
  180. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_6_1_byte.c +4 -4
  181. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_6byte.c +4 -4
  182. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_7_1_byte.c +4 -4
  183. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_7byte.c +4 -4
  184. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_8byte.c +4 -4
  185. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_9byte1.c +4 -4
  186. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_9byte2.c +4 -4
  187. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_double.c +4 -4
  188. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_float.c +4 -4
  189. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble.c +4 -4
  190. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble_split.c +4 -6
  191. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble_split2.c +4 -6
  192. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_pointer.c +4 -4
  193. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint16.c +4 -4
  194. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint32.c +4 -4
  195. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint64.c +4 -4
  196. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint16.c +4 -4
  197. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint32.c +4 -4
  198. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint64.c +4 -4
  199. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_dbls_struct.c +4 -4
  200. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_double_va.c +10 -9
  201. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_longdouble.c +3 -3
  202. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_longdouble_va.c +10 -9
  203. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_many_mixed_args.c +70 -0
  204. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_many_mixed_float_double.c +55 -0
  205. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_pointer.c +1 -1
  206. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_pointer_stack.c +11 -9
  207. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_struct_va1.c +114 -0
  208. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_uchar_va.c +44 -0
  209. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_uint_va.c +45 -0
  210. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_ulong_va.c +45 -0
  211. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_ulonglong.c +5 -5
  212. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_ushort_va.c +44 -0
  213. data/ext/ffi_c/libffi/testsuite/libffi.call/err_bad_typedef.c +2 -2
  214. data/ext/ffi_c/libffi/testsuite/libffi.call/ffitest.h +23 -40
  215. data/ext/ffi_c/libffi/testsuite/libffi.call/float1.c +3 -1
  216. data/ext/ffi_c/libffi/testsuite/libffi.call/float2.c +6 -4
  217. data/ext/ffi_c/libffi/testsuite/libffi.call/float3.c +4 -2
  218. data/ext/ffi_c/libffi/testsuite/libffi.call/float_va.c +107 -0
  219. data/ext/ffi_c/libffi/testsuite/libffi.call/huge_struct.c +18 -19
  220. data/ext/ffi_c/libffi/testsuite/libffi.call/many.c +6 -16
  221. data/ext/ffi_c/libffi/testsuite/libffi.call/many2.c +57 -0
  222. data/ext/ffi_c/libffi/testsuite/libffi.call/many_double.c +70 -0
  223. data/ext/ffi_c/libffi/testsuite/libffi.call/many_mixed.c +78 -0
  224. data/ext/ffi_c/libffi/testsuite/libffi.call/negint.c +0 -1
  225. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct.c +6 -6
  226. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct1.c +8 -8
  227. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct10.c +6 -6
  228. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct11.c +121 -0
  229. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct2.c +5 -5
  230. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct3.c +5 -5
  231. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct4.c +5 -5
  232. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct5.c +5 -5
  233. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct6.c +6 -6
  234. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct7.c +5 -5
  235. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct8.c +6 -6
  236. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct9.c +6 -6
  237. data/ext/ffi_c/libffi/testsuite/libffi.call/offsets.c +46 -0
  238. data/ext/ffi_c/libffi/testsuite/libffi.call/pr1172638.c +127 -0
  239. data/ext/ffi_c/libffi/testsuite/libffi.call/return_dbl.c +1 -0
  240. data/ext/ffi_c/libffi/testsuite/libffi.call/return_ldl.c +1 -1
  241. data/ext/ffi_c/libffi/testsuite/libffi.call/return_sc.c +1 -1
  242. data/ext/ffi_c/libffi/testsuite/libffi.call/return_uc.c +1 -1
  243. data/ext/ffi_c/libffi/testsuite/libffi.call/stret_large.c +7 -7
  244. data/ext/ffi_c/libffi/testsuite/libffi.call/stret_large2.c +7 -7
  245. data/ext/ffi_c/libffi/testsuite/libffi.call/stret_medium.c +5 -5
  246. data/ext/ffi_c/libffi/testsuite/libffi.call/stret_medium2.c +5 -5
  247. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen.c +2 -2
  248. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen2.c +49 -0
  249. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen3.c +49 -0
  250. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen4.c +55 -0
  251. data/ext/ffi_c/libffi/testsuite/libffi.call/struct1.c +9 -7
  252. data/ext/ffi_c/libffi/testsuite/libffi.call/struct2.c +7 -7
  253. data/ext/ffi_c/libffi/testsuite/libffi.call/struct3.c +7 -6
  254. data/ext/ffi_c/libffi/testsuite/libffi.call/struct4.c +9 -8
  255. data/ext/ffi_c/libffi/testsuite/libffi.call/struct5.c +9 -8
  256. data/ext/ffi_c/libffi/testsuite/libffi.call/struct6.c +9 -9
  257. data/ext/ffi_c/libffi/testsuite/libffi.call/struct7.c +9 -9
  258. data/ext/ffi_c/libffi/testsuite/libffi.call/struct8.c +9 -8
  259. data/ext/ffi_c/libffi/testsuite/libffi.call/struct9.c +9 -8
  260. data/ext/ffi_c/libffi/testsuite/libffi.call/testclosure.c +2 -2
  261. data/ext/ffi_c/libffi/testsuite/libffi.call/uninitialized.c +61 -0
  262. data/ext/ffi_c/libffi/testsuite/{libffi.special → libffi.call}/unwindtest.cc +3 -10
  263. data/ext/ffi_c/libffi/testsuite/{libffi.special → libffi.call}/unwindtest_ffi_call.cc +2 -1
  264. data/ext/ffi_c/libffi/testsuite/libffi.call/va_1.c +196 -0
  265. data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct1.c +121 -0
  266. data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct2.c +123 -0
  267. data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct3.c +125 -0
  268. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_align_complex.inc +91 -0
  269. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_align_complex_double.c +10 -0
  270. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_align_complex_float.c +10 -0
  271. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_align_complex_longdouble.c +10 -0
  272. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex.inc +42 -0
  273. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_double.c +10 -0
  274. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_float.c +10 -0
  275. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_longdouble.c +10 -0
  276. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_struct.inc +71 -0
  277. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_struct_double.c +10 -0
  278. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_struct_float.c +10 -0
  279. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_struct_longdouble.c +10 -0
  280. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_va.inc +80 -0
  281. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_va_double.c +10 -0
  282. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_va_float.c +16 -0
  283. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_va_longdouble.c +10 -0
  284. data/ext/ffi_c/libffi/testsuite/{libffi.special/special.exp → libffi.complex/complex.exp} +9 -8
  285. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex.inc +51 -0
  286. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_defs_double.inc +7 -0
  287. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_defs_float.inc +7 -0
  288. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_defs_longdouble.inc +7 -0
  289. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_double.c +10 -0
  290. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_float.c +10 -0
  291. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_int.c +86 -0
  292. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_longdouble.c +10 -0
  293. data/ext/ffi_c/libffi/testsuite/libffi.complex/ffitest.h +1 -0
  294. data/ext/ffi_c/libffi/testsuite/libffi.complex/many_complex.inc +78 -0
  295. data/ext/ffi_c/libffi/testsuite/libffi.complex/many_complex_double.c +10 -0
  296. data/ext/ffi_c/libffi/testsuite/libffi.complex/many_complex_float.c +10 -0
  297. data/ext/ffi_c/libffi/testsuite/libffi.complex/many_complex_longdouble.c +10 -0
  298. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex.inc +37 -0
  299. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex1.inc +41 -0
  300. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex1_double.c +10 -0
  301. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex1_float.c +10 -0
  302. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex1_longdouble.c +10 -0
  303. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex2.inc +44 -0
  304. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex2_double.c +10 -0
  305. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex2_float.c +10 -0
  306. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex2_longdouble.c +10 -0
  307. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex_double.c +10 -0
  308. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex_float.c +10 -0
  309. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex_longdouble.c +10 -0
  310. data/ext/ffi_c/libffi/testsuite/libffi.go/aa-direct.c +34 -0
  311. data/ext/ffi_c/libffi/testsuite/libffi.go/closure1.c +28 -0
  312. data/ext/ffi_c/libffi/testsuite/libffi.go/ffitest.h +1 -0
  313. data/ext/ffi_c/libffi/testsuite/libffi.go/go.exp +36 -0
  314. data/ext/ffi_c/libffi/testsuite/libffi.go/static-chain.h +19 -0
  315. data/ffi.gemspec +2 -2
  316. data/lib/ffi/enum.rb +124 -0
  317. data/lib/ffi/library.rb +65 -13
  318. data/lib/ffi/platform.rb +7 -2
  319. data/lib/ffi/platform/sparc64-linux/types.conf +102 -0
  320. data/lib/ffi/platform/x86_64-windows/types.conf +113 -20
  321. data/lib/ffi/pointer.rb +1 -0
  322. data/lib/ffi/struct.rb +0 -2
  323. data/lib/ffi/version.rb +1 -1
  324. data/spec/ffi/bitmask_spec.rb +575 -0
  325. data/spec/ffi/fixtures/BitmaskTest.c +51 -0
  326. data/spec/ffi/rbx/memory_pointer_spec.rb +4 -0
  327. data/spec/ffi/struct_spec.rb +0 -4
  328. metadata +143 -51
  329. data/ext/ffi_c/libffi/Makefile.in +0 -1820
  330. data/ext/ffi_c/libffi/Makefile.vc +0 -141
  331. data/ext/ffi_c/libffi/Makefile.vc64 +0 -141
  332. data/ext/ffi_c/libffi/aclocal.m4 +0 -1873
  333. data/ext/ffi_c/libffi/build-ios.sh +0 -67
  334. data/ext/ffi_c/libffi/compile +0 -143
  335. data/ext/ffi_c/libffi/config.guess +0 -1501
  336. data/ext/ffi_c/libffi/config.sub +0 -1705
  337. data/ext/ffi_c/libffi/configure +0 -17191
  338. data/ext/ffi_c/libffi/depcomp +0 -630
  339. data/ext/ffi_c/libffi/doc/libffi.info +0 -593
  340. data/ext/ffi_c/libffi/doc/stamp-vti +0 -4
  341. data/ext/ffi_c/libffi/fficonfig.h.in +0 -199
  342. data/ext/ffi_c/libffi/include/Makefile.in +0 -487
  343. data/ext/ffi_c/libffi/include/ffi.h.vc +0 -427
  344. data/ext/ffi_c/libffi/include/ffi.h.vc64 +0 -427
  345. data/ext/ffi_c/libffi/install-sh +0 -520
  346. data/ext/ffi_c/libffi/ltmain.sh +0 -9636
  347. data/ext/ffi_c/libffi/m4/libtool.m4 +0 -7831
  348. data/ext/ffi_c/libffi/m4/ltoptions.m4 +0 -369
  349. data/ext/ffi_c/libffi/m4/ltsugar.m4 +0 -123
  350. data/ext/ffi_c/libffi/m4/ltversion.m4 +0 -23
  351. data/ext/ffi_c/libffi/m4/lt~obsolete.m4 +0 -98
  352. data/ext/ffi_c/libffi/man/Makefile.in +0 -466
  353. data/ext/ffi_c/libffi/mdate-sh +0 -201
  354. data/ext/ffi_c/libffi/missing +0 -376
  355. data/ext/ffi_c/libffi/src/arm/gentramp.sh +0 -118
  356. data/ext/ffi_c/libffi/src/arm/trampoline.S +0 -4450
  357. data/ext/ffi_c/libffi/src/x86/darwin.S +0 -444
  358. data/ext/ffi_c/libffi/src/x86/darwin64.S +0 -416
  359. data/ext/ffi_c/libffi/src/x86/freebsd.S +0 -458
  360. data/ext/ffi_c/libffi/src/x86/win32.S +0 -1065
  361. data/ext/ffi_c/libffi/testsuite/Makefile.in +0 -500
  362. data/ext/ffi_c/libffi/testsuite/lib/libffi-dg.exp +0 -300
  363. data/ext/ffi_c/libffi/testsuite/libffi.call/many_win32.c +0 -63
  364. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen_win32.c +0 -44
  365. data/ext/ffi_c/libffi/testsuite/libffi.special/ffitestcxx.h +0 -96
  366. data/ext/ffi_c/libffi/texinfo.tex +0 -7210
@@ -1,9 +1,10 @@
1
1
  /* -----------------------------------------------------------------------
2
- ffi64.c - Copyright (c) 20011 Anthony Green
2
+ ffi64.c - Copyright (c) 2013 The Written Word, Inc.
3
+ Copyright (c) 2011 Anthony Green
3
4
  Copyright (c) 2008, 2010 Red Hat, Inc.
4
5
  Copyright (c) 2002, 2007 Bo Thorsen <bo@suse.de>
5
-
6
- x86-64 Foreign Function Interface
6
+
7
+ x86-64 Foreign Function Interface
7
8
 
8
9
  Permission is hereby granted, free of charge, to any person obtaining
9
10
  a copy of this software and associated documentation files (the
@@ -31,21 +32,44 @@
31
32
 
32
33
  #include <stdlib.h>
33
34
  #include <stdarg.h>
35
+ #include <stdint.h>
36
+ #include "internal64.h"
34
37
 
35
38
  #ifdef __x86_64__
36
39
 
37
40
  #define MAX_GPR_REGS 6
38
41
  #define MAX_SSE_REGS 8
39
42
 
43
+ #if defined(__INTEL_COMPILER)
44
+ #include "xmmintrin.h"
45
+ #define UINT128 __m128
46
+ #else
47
+ #if defined(__SUNPRO_C)
48
+ #include <sunmedia_types.h>
49
+ #define UINT128 __m128i
50
+ #else
51
+ #define UINT128 __int128_t
52
+ #endif
53
+ #endif
54
+
55
+ union big_int_union
56
+ {
57
+ UINT32 i32;
58
+ UINT64 i64;
59
+ UINT128 i128;
60
+ };
61
+
40
62
  struct register_args
41
63
  {
42
64
  /* Registers for argument passing. */
43
65
  UINT64 gpr[MAX_GPR_REGS];
44
- __int128_t sse[MAX_SSE_REGS];
66
+ union big_int_union sse[MAX_SSE_REGS];
67
+ UINT64 rax; /* ssecount */
68
+ UINT64 r10; /* static chain */
45
69
  };
46
70
 
47
71
  extern void ffi_call_unix64 (void *args, unsigned long bytes, unsigned flags,
48
- void *raddr, void (*fnaddr)(void), unsigned ssecount);
72
+ void *raddr, void (*fnaddr)(void)) FFI_HIDDEN;
49
73
 
50
74
  /* All reference to register classes here is identical to the code in
51
75
  gcc/config/i386/i386.c. Do *not* change one without the other. */
@@ -132,7 +156,7 @@ merge_classes (enum x86_64_reg_class class1, enum x86_64_reg_class class2)
132
156
 
133
157
  See the x86-64 PS ABI for details.
134
158
  */
135
- static int
159
+ static size_t
136
160
  classify_argument (ffi_type *type, enum x86_64_reg_class classes[],
137
161
  size_t byte_offset)
138
162
  {
@@ -147,8 +171,9 @@ classify_argument (ffi_type *type, enum x86_64_reg_class classes[],
147
171
  case FFI_TYPE_UINT64:
148
172
  case FFI_TYPE_SINT64:
149
173
  case FFI_TYPE_POINTER:
174
+ do_integer:
150
175
  {
151
- int size = byte_offset + type->size;
176
+ size_t size = byte_offset + type->size;
152
177
 
153
178
  if (size <= 4)
154
179
  {
@@ -168,7 +193,7 @@ classify_argument (ffi_type *type, enum x86_64_reg_class classes[],
168
193
  }
169
194
  else if (size <= 16)
170
195
  {
171
- classes[0] = classes[1] = X86_64_INTEGERSI_CLASS;
196
+ classes[0] = classes[1] = X86_64_INTEGER_CLASS;
172
197
  return 2;
173
198
  }
174
199
  else
@@ -183,16 +208,18 @@ classify_argument (ffi_type *type, enum x86_64_reg_class classes[],
183
208
  case FFI_TYPE_DOUBLE:
184
209
  classes[0] = X86_64_SSEDF_CLASS;
185
210
  return 1;
211
+ #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
186
212
  case FFI_TYPE_LONGDOUBLE:
187
213
  classes[0] = X86_64_X87_CLASS;
188
214
  classes[1] = X86_64_X87UP_CLASS;
189
215
  return 2;
216
+ #endif
190
217
  case FFI_TYPE_STRUCT:
191
218
  {
192
- const int UNITS_PER_WORD = 8;
193
- int words = (type->size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
194
- ffi_type **ptr;
195
- int i;
219
+ const size_t UNITS_PER_WORD = 8;
220
+ size_t words = (type->size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
221
+ ffi_type **ptr;
222
+ unsigned int i;
196
223
  enum x86_64_reg_class subclasses[MAX_CLASSES];
197
224
 
198
225
  /* If the struct is larger than 32 bytes, pass it on the stack. */
@@ -206,6 +233,7 @@ classify_argument (ffi_type *type, enum x86_64_reg_class classes[],
206
233
  signalize memory class, so handle it as special case. */
207
234
  if (!words)
208
235
  {
236
+ case FFI_TYPE_VOID:
209
237
  classes[0] = X86_64_NO_CLASS;
210
238
  return 1;
211
239
  }
@@ -213,16 +241,16 @@ classify_argument (ffi_type *type, enum x86_64_reg_class classes[],
213
241
  /* Merge the fields of structure. */
214
242
  for (ptr = type->elements; *ptr != NULL; ptr++)
215
243
  {
216
- int num;
244
+ size_t num;
217
245
 
218
- byte_offset = ALIGN (byte_offset, (*ptr)->alignment);
246
+ byte_offset = FFI_ALIGN (byte_offset, (*ptr)->alignment);
219
247
 
220
248
  num = classify_argument (*ptr, subclasses, byte_offset % 8);
221
249
  if (num == 0)
222
250
  return 0;
223
251
  for (i = 0; i < num; i++)
224
252
  {
225
- int pos = byte_offset / 8;
253
+ size_t pos = byte_offset / 8;
226
254
  classes[i + pos] =
227
255
  merge_classes (subclasses[i], classes[i + pos]);
228
256
  }
@@ -275,22 +303,55 @@ classify_argument (ffi_type *type, enum x86_64_reg_class classes[],
275
303
  }
276
304
  return words;
277
305
  }
278
-
279
- default:
280
- FFI_ASSERT(0);
306
+ case FFI_TYPE_COMPLEX:
307
+ {
308
+ ffi_type *inner = type->elements[0];
309
+ switch (inner->type)
310
+ {
311
+ case FFI_TYPE_INT:
312
+ case FFI_TYPE_UINT8:
313
+ case FFI_TYPE_SINT8:
314
+ case FFI_TYPE_UINT16:
315
+ case FFI_TYPE_SINT16:
316
+ case FFI_TYPE_UINT32:
317
+ case FFI_TYPE_SINT32:
318
+ case FFI_TYPE_UINT64:
319
+ case FFI_TYPE_SINT64:
320
+ goto do_integer;
321
+
322
+ case FFI_TYPE_FLOAT:
323
+ classes[0] = X86_64_SSE_CLASS;
324
+ if (byte_offset % 8)
325
+ {
326
+ classes[1] = X86_64_SSESF_CLASS;
327
+ return 2;
328
+ }
329
+ return 1;
330
+ case FFI_TYPE_DOUBLE:
331
+ classes[0] = classes[1] = X86_64_SSEDF_CLASS;
332
+ return 2;
333
+ #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
334
+ case FFI_TYPE_LONGDOUBLE:
335
+ classes[0] = X86_64_COMPLEX_X87_CLASS;
336
+ return 1;
337
+ #endif
338
+ }
339
+ }
281
340
  }
282
- return 0; /* Never reached. */
341
+ abort();
283
342
  }
284
343
 
285
344
  /* Examine the argument and return set number of register required in each
286
345
  class. Return zero iff parameter should be passed in memory, otherwise
287
346
  the number of registers. */
288
347
 
289
- static int
348
+ static size_t
290
349
  examine_argument (ffi_type *type, enum x86_64_reg_class classes[MAX_CLASSES],
291
350
  _Bool in_return, int *pngpr, int *pnsse)
292
351
  {
293
- int i, n, ngpr, nsse;
352
+ size_t n;
353
+ unsigned int i;
354
+ int ngpr, nsse;
294
355
 
295
356
  n = classify_argument (type, classes, 0);
296
357
  if (n == 0)
@@ -328,18 +389,67 @@ examine_argument (ffi_type *type, enum x86_64_reg_class classes[MAX_CLASSES],
328
389
 
329
390
  /* Perform machine dependent cif processing. */
330
391
 
392
+ extern ffi_status
393
+ ffi_prep_cif_machdep_efi64(ffi_cif *cif);
394
+
331
395
  ffi_status
332
396
  ffi_prep_cif_machdep (ffi_cif *cif)
333
397
  {
334
- int gprcount, ssecount, i, avn, n, ngpr, nsse, flags;
398
+ int gprcount, ssecount, i, avn, ngpr, nsse, flags;
335
399
  enum x86_64_reg_class classes[MAX_CLASSES];
336
- size_t bytes;
400
+ size_t bytes, n, rtype_size;
401
+ ffi_type *rtype;
402
+
403
+ if (cif->abi == FFI_EFI64)
404
+ return ffi_prep_cif_machdep_efi64(cif);
405
+ if (cif->abi != FFI_UNIX64)
406
+ return FFI_BAD_ABI;
337
407
 
338
408
  gprcount = ssecount = 0;
339
409
 
340
- flags = cif->rtype->type;
341
- if (flags != FFI_TYPE_VOID)
410
+ rtype = cif->rtype;
411
+ rtype_size = rtype->size;
412
+ switch (rtype->type)
342
413
  {
414
+ case FFI_TYPE_VOID:
415
+ flags = UNIX64_RET_VOID;
416
+ break;
417
+ case FFI_TYPE_UINT8:
418
+ flags = UNIX64_RET_UINT8;
419
+ break;
420
+ case FFI_TYPE_SINT8:
421
+ flags = UNIX64_RET_SINT8;
422
+ break;
423
+ case FFI_TYPE_UINT16:
424
+ flags = UNIX64_RET_UINT16;
425
+ break;
426
+ case FFI_TYPE_SINT16:
427
+ flags = UNIX64_RET_SINT16;
428
+ break;
429
+ case FFI_TYPE_UINT32:
430
+ flags = UNIX64_RET_UINT32;
431
+ break;
432
+ case FFI_TYPE_INT:
433
+ case FFI_TYPE_SINT32:
434
+ flags = UNIX64_RET_SINT32;
435
+ break;
436
+ case FFI_TYPE_UINT64:
437
+ case FFI_TYPE_SINT64:
438
+ flags = UNIX64_RET_INT64;
439
+ break;
440
+ case FFI_TYPE_POINTER:
441
+ flags = (sizeof(void *) == 4 ? UNIX64_RET_UINT32 : UNIX64_RET_INT64);
442
+ break;
443
+ case FFI_TYPE_FLOAT:
444
+ flags = UNIX64_RET_XMM32;
445
+ break;
446
+ case FFI_TYPE_DOUBLE:
447
+ flags = UNIX64_RET_XMM64;
448
+ break;
449
+ case FFI_TYPE_LONGDOUBLE:
450
+ flags = UNIX64_RET_X87;
451
+ break;
452
+ case FFI_TYPE_STRUCT:
343
453
  n = examine_argument (cif->rtype, classes, 1, &ngpr, &nsse);
344
454
  if (n == 0)
345
455
  {
@@ -347,22 +457,62 @@ ffi_prep_cif_machdep (ffi_cif *cif)
347
457
  memory is the first argument. Allocate a register for it. */
348
458
  gprcount++;
349
459
  /* We don't have to do anything in asm for the return. */
350
- flags = FFI_TYPE_VOID;
460
+ flags = UNIX64_RET_VOID | UNIX64_FLAG_RET_IN_MEM;
351
461
  }
352
- else if (flags == FFI_TYPE_STRUCT)
462
+ else
353
463
  {
354
- /* Mark which registers the result appears in. */
355
464
  _Bool sse0 = SSE_CLASS_P (classes[0]);
356
- _Bool sse1 = n == 2 && SSE_CLASS_P (classes[1]);
357
- if (sse0 && !sse1)
358
- flags |= 1 << 8;
359
- else if (!sse0 && sse1)
360
- flags |= 1 << 9;
361
- else if (sse0 && sse1)
362
- flags |= 1 << 10;
363
- /* Mark the true size of the structure. */
364
- flags |= cif->rtype->size << 12;
465
+
466
+ if (rtype_size == 4 && sse0)
467
+ flags = UNIX64_RET_XMM32;
468
+ else if (rtype_size == 8)
469
+ flags = sse0 ? UNIX64_RET_XMM64 : UNIX64_RET_INT64;
470
+ else
471
+ {
472
+ _Bool sse1 = n == 2 && SSE_CLASS_P (classes[1]);
473
+ if (sse0 && sse1)
474
+ flags = UNIX64_RET_ST_XMM0_XMM1;
475
+ else if (sse0)
476
+ flags = UNIX64_RET_ST_XMM0_RAX;
477
+ else if (sse1)
478
+ flags = UNIX64_RET_ST_RAX_XMM0;
479
+ else
480
+ flags = UNIX64_RET_ST_RAX_RDX;
481
+ flags |= rtype_size << UNIX64_SIZE_SHIFT;
482
+ }
483
+ }
484
+ break;
485
+ case FFI_TYPE_COMPLEX:
486
+ switch (rtype->elements[0]->type)
487
+ {
488
+ case FFI_TYPE_UINT8:
489
+ case FFI_TYPE_SINT8:
490
+ case FFI_TYPE_UINT16:
491
+ case FFI_TYPE_SINT16:
492
+ case FFI_TYPE_INT:
493
+ case FFI_TYPE_UINT32:
494
+ case FFI_TYPE_SINT32:
495
+ case FFI_TYPE_UINT64:
496
+ case FFI_TYPE_SINT64:
497
+ flags = UNIX64_RET_ST_RAX_RDX | (rtype_size << UNIX64_SIZE_SHIFT);
498
+ break;
499
+ case FFI_TYPE_FLOAT:
500
+ flags = UNIX64_RET_XMM64;
501
+ break;
502
+ case FFI_TYPE_DOUBLE:
503
+ flags = UNIX64_RET_ST_XMM0_XMM1 | (16 << UNIX64_SIZE_SHIFT);
504
+ break;
505
+ #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
506
+ case FFI_TYPE_LONGDOUBLE:
507
+ flags = UNIX64_RET_X87_2;
508
+ break;
509
+ #endif
510
+ default:
511
+ return FFI_BAD_TYPEDEF;
365
512
  }
513
+ break;
514
+ default:
515
+ return FFI_BAD_TYPEDEF;
366
516
  }
367
517
 
368
518
  /* Go over all arguments and determine the way they should be passed.
@@ -379,7 +529,7 @@ ffi_prep_cif_machdep (ffi_cif *cif)
379
529
  if (align < 8)
380
530
  align = 8;
381
531
 
382
- bytes = ALIGN (bytes, align);
532
+ bytes = FFI_ALIGN (bytes, align);
383
533
  bytes += cif->arg_types[i]->size;
384
534
  }
385
535
  else
@@ -389,53 +539,58 @@ ffi_prep_cif_machdep (ffi_cif *cif)
389
539
  }
390
540
  }
391
541
  if (ssecount)
392
- flags |= 1 << 11;
542
+ flags |= UNIX64_FLAG_XMM_ARGS;
543
+
393
544
  cif->flags = flags;
394
- cif->bytes = ALIGN (bytes, 8);
545
+ cif->bytes = FFI_ALIGN (bytes, 8);
395
546
 
396
547
  return FFI_OK;
397
548
  }
398
549
 
399
- void
400
- ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
550
+ static void
551
+ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue,
552
+ void **avalue, void *closure)
401
553
  {
402
554
  enum x86_64_reg_class classes[MAX_CLASSES];
403
555
  char *stack, *argp;
404
556
  ffi_type **arg_types;
405
- int gprcount, ssecount, ngpr, nsse, i, avn;
406
- _Bool ret_in_memory;
557
+ int gprcount, ssecount, ngpr, nsse, i, avn, flags;
407
558
  struct register_args *reg_args;
408
559
 
409
560
  /* Can't call 32-bit mode from 64-bit mode. */
410
561
  FFI_ASSERT (cif->abi == FFI_UNIX64);
411
562
 
412
563
  /* If the return value is a struct and we don't have a return value
413
- address then we need to make one. Note the setting of flags to
414
- VOID above in ffi_prep_cif_machdep. */
415
- ret_in_memory = (cif->rtype->type == FFI_TYPE_STRUCT
416
- && (cif->flags & 0xff) == FFI_TYPE_VOID);
417
- if (rvalue == NULL && ret_in_memory)
418
- rvalue = alloca (cif->rtype->size);
564
+ address then we need to make one. Otherwise we can ignore it. */
565
+ flags = cif->flags;
566
+ if (rvalue == NULL)
567
+ {
568
+ if (flags & UNIX64_FLAG_RET_IN_MEM)
569
+ rvalue = alloca (cif->rtype->size);
570
+ else
571
+ flags = UNIX64_RET_VOID;
572
+ }
419
573
 
420
574
  /* Allocate the space for the arguments, plus 4 words of temp space. */
421
575
  stack = alloca (sizeof (struct register_args) + cif->bytes + 4*8);
422
576
  reg_args = (struct register_args *) stack;
423
577
  argp = stack + sizeof (struct register_args);
424
578
 
579
+ reg_args->r10 = (uintptr_t) closure;
580
+
425
581
  gprcount = ssecount = 0;
426
582
 
427
583
  /* If the return value is passed in memory, add the pointer as the
428
584
  first integer argument. */
429
- if (ret_in_memory)
430
- reg_args->gpr[gprcount++] = (long) rvalue;
585
+ if (flags & UNIX64_FLAG_RET_IN_MEM)
586
+ reg_args->gpr[gprcount++] = (unsigned long) rvalue;
431
587
 
432
588
  avn = cif->nargs;
433
589
  arg_types = cif->arg_types;
434
590
 
435
591
  for (i = 0; i < avn; ++i)
436
592
  {
437
- size_t size = arg_types[i]->size;
438
- int n;
593
+ size_t n, size = arg_types[i]->size;
439
594
 
440
595
  n = examine_argument (arg_types[i], classes, 0, &ngpr, &nsse);
441
596
  if (n == 0
@@ -449,7 +604,7 @@ ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
449
604
  align = 8;
450
605
 
451
606
  /* Pass this argument in memory. */
452
- argp = (void *) ALIGN (argp, align);
607
+ argp = (void *) FFI_ALIGN (argp, align);
453
608
  memcpy (argp, avalue[i], size);
454
609
  argp += size;
455
610
  }
@@ -457,24 +612,44 @@ ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
457
612
  {
458
613
  /* The argument is passed entirely in registers. */
459
614
  char *a = (char *) avalue[i];
460
- int j;
615
+ unsigned int j;
461
616
 
462
617
  for (j = 0; j < n; j++, a += 8, size -= 8)
463
618
  {
464
619
  switch (classes[j])
465
620
  {
621
+ case X86_64_NO_CLASS:
622
+ case X86_64_SSEUP_CLASS:
623
+ break;
466
624
  case X86_64_INTEGER_CLASS:
467
625
  case X86_64_INTEGERSI_CLASS:
468
- reg_args->gpr[gprcount] = 0;
469
- memcpy (&reg_args->gpr[gprcount], a, size < 8 ? size : 8);
626
+ /* Sign-extend integer arguments passed in general
627
+ purpose registers, to cope with the fact that
628
+ LLVM incorrectly assumes that this will be done
629
+ (the x86-64 PS ABI does not specify this). */
630
+ switch (arg_types[i]->type)
631
+ {
632
+ case FFI_TYPE_SINT8:
633
+ reg_args->gpr[gprcount] = (SINT64) *((SINT8 *) a);
634
+ break;
635
+ case FFI_TYPE_SINT16:
636
+ reg_args->gpr[gprcount] = (SINT64) *((SINT16 *) a);
637
+ break;
638
+ case FFI_TYPE_SINT32:
639
+ reg_args->gpr[gprcount] = (SINT64) *((SINT32 *) a);
640
+ break;
641
+ default:
642
+ reg_args->gpr[gprcount] = 0;
643
+ memcpy (&reg_args->gpr[gprcount], a, size);
644
+ }
470
645
  gprcount++;
471
646
  break;
472
647
  case X86_64_SSE_CLASS:
473
648
  case X86_64_SSEDF_CLASS:
474
- reg_args->sse[ssecount++] = *(UINT64 *) a;
649
+ reg_args->sse[ssecount++].i64 = *(UINT64 *) a;
475
650
  break;
476
651
  case X86_64_SSESF_CLASS:
477
- reg_args->sse[ssecount++] = *(UINT32 *) a;
652
+ reg_args->sse[ssecount++].i32 = *(UINT32 *) a;
478
653
  break;
479
654
  default:
480
655
  abort();
@@ -482,13 +657,46 @@ ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
482
657
  }
483
658
  }
484
659
  }
660
+ reg_args->rax = ssecount;
485
661
 
486
662
  ffi_call_unix64 (stack, cif->bytes + sizeof (struct register_args),
487
- cif->flags, rvalue, fn, ssecount);
663
+ flags, rvalue, fn);
488
664
  }
489
665
 
666
+ extern void
667
+ ffi_call_efi64(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue);
490
668
 
491
- extern void ffi_closure_unix64(void);
669
+ void
670
+ ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
671
+ {
672
+ if (cif->abi == FFI_EFI64)
673
+ return ffi_call_efi64(cif, fn, rvalue, avalue);
674
+ ffi_call_int (cif, fn, rvalue, avalue, NULL);
675
+ }
676
+
677
+ extern void
678
+ ffi_call_go_efi64(ffi_cif *cif, void (*fn)(void), void *rvalue,
679
+ void **avalue, void *closure);
680
+
681
+ void
682
+ ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue,
683
+ void **avalue, void *closure)
684
+ {
685
+ if (cif->abi == FFI_EFI64)
686
+ ffi_call_go_efi64(cif, fn, rvalue, avalue, closure);
687
+ ffi_call_int (cif, fn, rvalue, avalue, closure);
688
+ }
689
+
690
+
691
+ extern void ffi_closure_unix64(void) FFI_HIDDEN;
692
+ extern void ffi_closure_unix64_sse(void) FFI_HIDDEN;
693
+
694
+ extern ffi_status
695
+ ffi_prep_closure_loc_efi64(ffi_closure* closure,
696
+ ffi_cif* cif,
697
+ void (*fun)(ffi_cif*, void*, void**, void*),
698
+ void *user_data,
699
+ void *codeloc);
492
700
 
493
701
  ffi_status
494
702
  ffi_prep_closure_loc (ffi_closure* closure,
@@ -497,27 +705,29 @@ ffi_prep_closure_loc (ffi_closure* closure,
497
705
  void *user_data,
498
706
  void *codeloc)
499
707
  {
500
- volatile unsigned short *tramp;
501
-
502
- /* Sanity check on the cif ABI. */
503
- {
504
- int abi = cif->abi;
505
- if (UNLIKELY (! (abi > FFI_FIRST_ABI && abi < FFI_LAST_ABI)))
506
- return FFI_BAD_ABI;
507
- }
508
-
509
- tramp = (volatile unsigned short *) &closure->tramp[0];
708
+ static const unsigned char trampoline[16] = {
709
+ /* leaq -0x7(%rip),%r10 # 0x0 */
710
+ 0x4c, 0x8d, 0x15, 0xf9, 0xff, 0xff, 0xff,
711
+ /* jmpq *0x3(%rip) # 0x10 */
712
+ 0xff, 0x25, 0x03, 0x00, 0x00, 0x00,
713
+ /* nopl (%rax) */
714
+ 0x0f, 0x1f, 0x00
715
+ };
716
+ void (*dest)(void);
717
+ char *tramp = closure->tramp;
510
718
 
511
- tramp[0] = 0xbb49; /* mov <code>, %r11 */
512
- *(void * volatile *) &tramp[1] = ffi_closure_unix64;
513
- tramp[5] = 0xba49; /* mov <data>, %r10 */
514
- *(void * volatile *) &tramp[6] = codeloc;
719
+ if (cif->abi == FFI_EFI64)
720
+ return ffi_prep_closure_loc_efi64(closure, cif, fun, user_data, codeloc);
721
+ if (cif->abi != FFI_UNIX64)
722
+ return FFI_BAD_ABI;
515
723
 
516
- /* Set the carry bit iff the function uses any sse registers.
517
- This is clc or stc, together with the first byte of the jmp. */
518
- tramp[10] = cif->flags & (1 << 11) ? 0x49f9 : 0x49f8;
724
+ if (cif->flags & UNIX64_FLAG_XMM_ARGS)
725
+ dest = ffi_closure_unix64_sse;
726
+ else
727
+ dest = ffi_closure_unix64;
519
728
 
520
- tramp[11] = 0xe3ff; /* jmp *%r11 */
729
+ memcpy (tramp, trampoline, sizeof(trampoline));
730
+ *(UINT64 *)(tramp + 16) = (uintptr_t)dest;
521
731
 
522
732
  closure->cif = cif;
523
733
  closure->fun = fun;
@@ -526,53 +736,40 @@ ffi_prep_closure_loc (ffi_closure* closure,
526
736
  return FFI_OK;
527
737
  }
528
738
 
529
- int
530
- ffi_closure_unix64_inner(ffi_closure *closure, void *rvalue,
531
- struct register_args *reg_args, char *argp)
739
+ int FFI_HIDDEN
740
+ ffi_closure_unix64_inner(ffi_cif *cif,
741
+ void (*fun)(ffi_cif*, void*, void**, void*),
742
+ void *user_data,
743
+ void *rvalue,
744
+ struct register_args *reg_args,
745
+ char *argp)
532
746
  {
533
- ffi_cif *cif;
534
747
  void **avalue;
535
748
  ffi_type **arg_types;
536
749
  long i, avn;
537
750
  int gprcount, ssecount, ngpr, nsse;
538
- int ret;
751
+ int flags;
539
752
 
540
- cif = closure->cif;
541
- avalue = alloca(cif->nargs * sizeof(void *));
753
+ avn = cif->nargs;
754
+ flags = cif->flags;
755
+ avalue = alloca(avn * sizeof(void *));
542
756
  gprcount = ssecount = 0;
543
757
 
544
- ret = cif->rtype->type;
545
- if (ret != FFI_TYPE_VOID)
758
+ if (flags & UNIX64_FLAG_RET_IN_MEM)
546
759
  {
547
- enum x86_64_reg_class classes[MAX_CLASSES];
548
- int n = examine_argument (cif->rtype, classes, 1, &ngpr, &nsse);
549
- if (n == 0)
550
- {
551
- /* The return value goes in memory. Arrange for the closure
552
- return value to go directly back to the original caller. */
553
- rvalue = (void *) reg_args->gpr[gprcount++];
554
- /* We don't have to do anything in asm for the return. */
555
- ret = FFI_TYPE_VOID;
556
- }
557
- else if (ret == FFI_TYPE_STRUCT && n == 2)
558
- {
559
- /* Mark which register the second word of the structure goes in. */
560
- _Bool sse0 = SSE_CLASS_P (classes[0]);
561
- _Bool sse1 = SSE_CLASS_P (classes[1]);
562
- if (!sse0 && sse1)
563
- ret |= 1 << 8;
564
- else if (sse0 && !sse1)
565
- ret |= 1 << 9;
566
- }
760
+ /* On return, %rax will contain the address that was passed
761
+ by the caller in %rdi. */
762
+ void *r = (void *)(uintptr_t)reg_args->gpr[gprcount++];
763
+ *(void **)rvalue = r;
764
+ rvalue = r;
765
+ flags = (sizeof(void *) == 4 ? UNIX64_RET_UINT32 : UNIX64_RET_INT64);
567
766
  }
568
767
 
569
- avn = cif->nargs;
570
768
  arg_types = cif->arg_types;
571
-
572
769
  for (i = 0; i < avn; ++i)
573
770
  {
574
771
  enum x86_64_reg_class classes[MAX_CLASSES];
575
- int n;
772
+ size_t n;
576
773
 
577
774
  n = examine_argument (arg_types[i], classes, 0, &ngpr, &nsse);
578
775
  if (n == 0
@@ -586,7 +783,7 @@ ffi_closure_unix64_inner(ffi_closure *closure, void *rvalue,
586
783
  align = 8;
587
784
 
588
785
  /* Pass this argument in memory. */
589
- argp = (void *) ALIGN (argp, align);
786
+ argp = (void *) FFI_ALIGN (argp, align);
590
787
  avalue[i] = argp;
591
788
  argp += arg_types[i]->size;
592
789
  }
@@ -612,7 +809,7 @@ ffi_closure_unix64_inner(ffi_closure *closure, void *rvalue,
612
809
  else
613
810
  {
614
811
  char *a = alloca (16);
615
- int j;
812
+ unsigned int j;
616
813
 
617
814
  avalue[i] = a;
618
815
  for (j = 0; j < n; j++, a += 8)
@@ -626,10 +823,35 @@ ffi_closure_unix64_inner(ffi_closure *closure, void *rvalue,
626
823
  }
627
824
 
628
825
  /* Invoke the closure. */
629
- closure->fun (cif, rvalue, avalue, closure->user_data);
826
+ fun (cif, rvalue, avalue, user_data);
630
827
 
631
828
  /* Tell assembly how to perform return type promotions. */
632
- return ret;
829
+ return flags;
830
+ }
831
+
832
+ extern void ffi_go_closure_unix64(void) FFI_HIDDEN;
833
+ extern void ffi_go_closure_unix64_sse(void) FFI_HIDDEN;
834
+
835
+ extern ffi_status
836
+ ffi_prep_go_closure_efi64(ffi_go_closure* closure, ffi_cif* cif,
837
+ void (*fun)(ffi_cif*, void*, void**, void*));
838
+
839
+ ffi_status
840
+ ffi_prep_go_closure (ffi_go_closure* closure, ffi_cif* cif,
841
+ void (*fun)(ffi_cif*, void*, void**, void*))
842
+ {
843
+ if (cif->abi == FFI_EFI64)
844
+ return ffi_prep_go_closure_efi64(closure, cif, fun);
845
+ if (cif->abi != FFI_UNIX64)
846
+ return FFI_BAD_ABI;
847
+
848
+ closure->tramp = (cif->flags & UNIX64_FLAG_XMM_ARGS
849
+ ? ffi_go_closure_unix64_sse
850
+ : ffi_go_closure_unix64);
851
+ closure->cif = cif;
852
+ closure->fun = fun;
853
+
854
+ return FFI_OK;
633
855
  }
634
856
 
635
857
  #endif /* __x86_64__ */