ffi 1.12.2 → 1.14.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 (135) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +82 -0
  3. data/Gemfile +4 -2
  4. data/README.md +10 -2
  5. data/Rakefile +31 -43
  6. data/ext/ffi_c/AbstractMemory.c +24 -25
  7. data/ext/ffi_c/Buffer.c +4 -9
  8. data/ext/ffi_c/Call.c +3 -14
  9. data/ext/ffi_c/ClosurePool.c +75 -25
  10. data/ext/ffi_c/ClosurePool.h +3 -1
  11. data/ext/ffi_c/DynamicLibrary.c +1 -6
  12. data/ext/ffi_c/Function.c +15 -35
  13. data/ext/ffi_c/FunctionInfo.c +3 -8
  14. data/ext/ffi_c/LastError.c +2 -6
  15. data/ext/ffi_c/LongDouble.c +5 -3
  16. data/ext/ffi_c/LongDouble.h +0 -4
  17. data/ext/ffi_c/MemoryPointer.c +3 -8
  18. data/ext/ffi_c/MethodHandle.c +21 -31
  19. data/ext/ffi_c/MethodHandle.h +3 -2
  20. data/ext/ffi_c/Platform.c +3 -7
  21. data/ext/ffi_c/Pointer.c +25 -26
  22. data/ext/ffi_c/Struct.c +3 -6
  23. data/ext/ffi_c/StructByValue.c +2 -7
  24. data/ext/ffi_c/StructLayout.c +9 -7
  25. data/ext/ffi_c/Thread.c +0 -8
  26. data/ext/ffi_c/Thread.h +1 -9
  27. data/ext/ffi_c/Type.c +1 -1
  28. data/ext/ffi_c/Variadic.c +2 -7
  29. data/ext/ffi_c/compat.h +4 -0
  30. data/ext/ffi_c/extconf.rb +33 -23
  31. data/ext/ffi_c/libffi/.travis.yml +4 -0
  32. data/ext/ffi_c/libffi/.travis/bfin-sim.exp +1 -1
  33. data/ext/ffi_c/libffi/.travis/build.sh +4 -0
  34. data/ext/ffi_c/libffi/.travis/m32r-sim.exp +1 -1
  35. data/ext/ffi_c/libffi/.travis/moxie-sim.exp +1 -1
  36. data/ext/ffi_c/libffi/.travis/or1k-sim.exp +1 -1
  37. data/ext/ffi_c/libffi/.travis/powerpc-eabisim.exp +1 -1
  38. data/ext/ffi_c/libffi/.travis/wine-sim.exp +1 -1
  39. data/ext/ffi_c/libffi/Makefile.am +49 -58
  40. data/ext/ffi_c/libffi/README.md +11 -1
  41. data/ext/ffi_c/libffi/config.guess +552 -331
  42. data/ext/ffi_c/libffi/config.sub +1321 -1306
  43. data/ext/ffi_c/libffi/configure.ac +31 -10
  44. data/ext/ffi_c/libffi/configure.host +32 -20
  45. data/ext/ffi_c/libffi/doc/Makefile.am +3 -0
  46. data/ext/ffi_c/libffi/doc/libffi.texi +997 -0
  47. data/ext/ffi_c/libffi/doc/version.texi +4 -0
  48. data/ext/ffi_c/libffi/generate-darwin-source-and-headers.py +1 -1
  49. data/ext/ffi_c/libffi/include/ffi.h.in +8 -0
  50. data/ext/ffi_c/libffi/libffi.map.in +8 -12
  51. data/ext/ffi_c/libffi/libtool-version +1 -1
  52. data/ext/ffi_c/libffi/msvcc.sh +11 -11
  53. data/ext/ffi_c/libffi/src/aarch64/ffi.c +51 -35
  54. data/ext/ffi_c/libffi/src/aarch64/ffitarget.h +10 -5
  55. data/ext/ffi_c/libffi/src/aarch64/internal.h +1 -0
  56. data/ext/ffi_c/libffi/src/aarch64/sysv.S +14 -3
  57. data/ext/ffi_c/libffi/src/aarch64/win64_armasm.S +1 -1
  58. data/ext/ffi_c/libffi/src/arm/ffi.c +22 -0
  59. data/ext/ffi_c/libffi/src/arm/sysv.S +4 -4
  60. data/ext/ffi_c/libffi/src/closures.c +33 -10
  61. data/ext/ffi_c/libffi/src/csky/ffi.c +395 -0
  62. data/ext/ffi_c/libffi/src/csky/ffitarget.h +63 -0
  63. data/ext/ffi_c/libffi/src/csky/sysv.S +371 -0
  64. data/ext/ffi_c/libffi/src/dlmalloc.c +1 -1
  65. data/ext/ffi_c/libffi/src/kvx/asm.h +5 -0
  66. data/ext/ffi_c/libffi/src/kvx/ffi.c +273 -0
  67. data/ext/ffi_c/libffi/src/kvx/ffitarget.h +75 -0
  68. data/ext/ffi_c/libffi/src/kvx/sysv.S +127 -0
  69. data/ext/ffi_c/libffi/src/mips/ffi.c +5 -1
  70. data/ext/ffi_c/libffi/src/mips/ffitarget.h +1 -1
  71. data/ext/ffi_c/libffi/src/pa/ffi.c +46 -91
  72. data/ext/ffi_c/libffi/src/pa/ffitarget.h +1 -6
  73. data/ext/ffi_c/libffi/src/pa/hpux32.S +4 -2
  74. data/ext/ffi_c/libffi/src/pa/linux.S +4 -2
  75. data/ext/ffi_c/libffi/src/powerpc/ffi_darwin.c +13 -1
  76. data/ext/ffi_c/libffi/src/powerpc/ffi_powerpc.h +1 -1
  77. data/ext/ffi_c/libffi/src/powerpc/linux64.S +8 -0
  78. data/ext/ffi_c/libffi/src/powerpc/linux64_closure.S +13 -1
  79. data/ext/ffi_c/libffi/src/powerpc/sysv.S +5 -7
  80. data/ext/ffi_c/libffi/src/prep_cif.c +1 -1
  81. data/ext/ffi_c/libffi/src/x86/ffi.c +15 -6
  82. data/ext/ffi_c/libffi/src/x86/ffi64.c +17 -8
  83. data/ext/ffi_c/libffi/src/x86/ffitarget.h +15 -2
  84. data/ext/ffi_c/libffi/src/x86/ffiw64.c +15 -8
  85. data/ext/ffi_c/libffi/src/x86/sysv.S +15 -6
  86. data/ext/ffi_c/libffi/src/x86/unix64.S +59 -4
  87. data/ext/ffi_c/libffi/src/x86/win64.S +7 -3
  88. data/ext/ffi_c/libffi/src/x86/win64_intel.S +3 -2
  89. data/ext/ffi_c/libffi/testsuite/lib/libffi.exp +22 -2
  90. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/test-call.c +4 -4
  91. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/test-callback.c +2 -2
  92. data/ext/ffi_c/libffi/testsuite/libffi.closures/huge_struct.c +2 -0
  93. data/ffi.gemspec +2 -2
  94. data/lib/ffi.rb +10 -2
  95. data/lib/ffi/abstract_memory.rb +44 -0
  96. data/lib/ffi/autopointer.rb +1 -1
  97. data/lib/ffi/ffi.rb +1 -0
  98. data/lib/ffi/io.rb +3 -3
  99. data/lib/ffi/library.rb +6 -2
  100. data/lib/ffi/managedstruct.rb +2 -2
  101. data/lib/ffi/platform.rb +21 -8
  102. data/lib/ffi/platform/aarch64-darwin/types.conf +130 -0
  103. data/lib/ffi/platform/aarch64-openbsd/types.conf +134 -0
  104. data/lib/ffi/platform/arm-linux/types.conf +32 -4
  105. data/lib/ffi/platform/i386-windows/types.conf +26 -79
  106. data/lib/ffi/platform/powerpc-linux/types.conf +32 -2
  107. data/lib/ffi/platform/powerpc-openbsd/types.conf +156 -0
  108. data/lib/ffi/platform/sparcv9-openbsd/types.conf +156 -0
  109. data/lib/ffi/platform/x86_64-darwin/types.conf +4 -0
  110. data/lib/ffi/platform/x86_64-dragonflybsd/types.conf +4 -22
  111. data/lib/ffi/platform/x86_64-haiku/types.conf +117 -0
  112. data/lib/ffi/platform/x86_64-linux/types.conf +21 -0
  113. data/lib/ffi/platform/x86_64-msys/types.conf +119 -0
  114. data/lib/ffi/platform/x86_64-windows/types.conf +10 -78
  115. data/lib/ffi/pointer.rb +21 -14
  116. data/lib/ffi/struct.rb +8 -2
  117. data/lib/ffi/tools/types_generator.rb +2 -0
  118. data/lib/ffi/variadic.rb +1 -1
  119. data/lib/ffi/version.rb +1 -1
  120. data/samples/getlogin.rb +1 -1
  121. data/samples/getpid.rb +1 -1
  122. data/samples/gettimeofday.rb +8 -8
  123. data/samples/hello.rb +2 -1
  124. data/samples/inotify.rb +1 -1
  125. data/samples/pty.rb +1 -2
  126. data/samples/qsort.rb +0 -1
  127. metadata +18 -12
  128. data/.appveyor.yml +0 -27
  129. data/.gitignore +0 -25
  130. data/.gitmodules +0 -4
  131. data/.travis.yml +0 -44
  132. data/.yardopts +0 -5
  133. data/ext/ffi_c/win32/stdbool.h +0 -8
  134. data/ext/ffi_c/win32/stdint.h +0 -201
  135. data/samples/sample_helper.rb +0 -6
@@ -129,11 +129,11 @@ ARM_FUNC_START(ffi_call_VFP)
129
129
 
130
130
  cmp r3, #3 @ load only d0 if possible
131
131
  #ifdef __clang__
132
- vldrle d0, [sp]
133
- vldmgt sp, {d0-d7}
132
+ vldrle d0, [r0]
133
+ vldmgt r0, {d0-d7}
134
134
  #else
135
- ldcle p11, cr0, [r0] @ vldrle d0, [sp]
136
- ldcgt p11, cr0, [r0], {16} @ vldmgt sp, {d0-d7}
135
+ ldcle p11, cr0, [r0] @ vldrle d0, [r0]
136
+ ldcgt p11, cr0, [r0], {16} @ vldmgt r0, {d0-d7}
137
137
  #endif
138
138
  add r0, r0, #64 @ discard the vfp register args
139
139
  /* FALLTHRU */
@@ -45,6 +45,9 @@
45
45
 
46
46
  #include <stddef.h>
47
47
  #include <unistd.h>
48
+ #ifdef HAVE_SYS_MEMFD_H
49
+ #include <sys/memfd.h>
50
+ #endif
48
51
 
49
52
  static const size_t overhead =
50
53
  (sizeof(max_align_t) > sizeof(void *) + sizeof(size_t)) ?
@@ -123,7 +126,7 @@ ffi_closure_free (void *ptr)
123
126
  # define FFI_MMAP_EXEC_WRIT 1
124
127
  # define HAVE_MNTENT 1
125
128
  # endif
126
- # if defined(X86_WIN32) || defined(X86_WIN64) || defined(_M_ARM64) || defined(__OS2__)
129
+ # if defined(_WIN32) || defined(__OS2__)
127
130
  /* Windows systems may have Data Execution Protection (DEP) enabled,
128
131
  which requires the use of VirtualMalloc/VirtualFree to alloc/free
129
132
  executable memory. */
@@ -148,6 +151,9 @@ ffi_closure_free (void *ptr)
148
151
 
149
152
  #include <mach/mach.h>
150
153
  #include <pthread.h>
154
+ #ifdef HAVE_PTRAUTH
155
+ #include <ptrauth.h>
156
+ #endif
151
157
  #include <stdio.h>
152
158
  #include <stdlib.h>
153
159
 
@@ -301,6 +307,9 @@ ffi_closure_alloc (size_t size, void **code)
301
307
 
302
308
  /* Initialize the return values */
303
309
  *code = entry->trampoline;
310
+ #ifdef HAVE_PTRAUTH
311
+ *code = ptrauth_sign_unauthenticated (*code, ptrauth_key_asia, 0);
312
+ #endif
304
313
  closure->trampoline_table = table;
305
314
  closure->trampoline_table_entry = entry;
306
315
 
@@ -386,7 +395,7 @@ ffi_closure_free (void *ptr)
386
395
  #endif
387
396
  #include <string.h>
388
397
  #include <stdio.h>
389
- #if !defined(X86_WIN32) && !defined(X86_WIN64) && !defined(_M_ARM64)
398
+ #if !defined(_WIN32)
390
399
  #ifdef HAVE_MNTENT
391
400
  #include <mntent.h>
392
401
  #endif /* HAVE_MNTENT */
@@ -512,11 +521,11 @@ static int dlmalloc_trim(size_t) MAYBE_UNUSED;
512
521
  static size_t dlmalloc_usable_size(void*) MAYBE_UNUSED;
513
522
  static void dlmalloc_stats(void) MAYBE_UNUSED;
514
523
 
515
- #if !(defined(X86_WIN32) || defined(X86_WIN64) || defined(_M_ARM64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX)
524
+ #if !(defined(_WIN32) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX)
516
525
  /* Use these for mmap and munmap within dlmalloc.c. */
517
526
  static void *dlmmap(void *, size_t, int, int, int, off_t);
518
527
  static int dlmunmap(void *, size_t);
519
- #endif /* !(defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX) */
528
+ #endif /* !(defined(_WIN32) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX) */
520
529
 
521
530
  #define mmap dlmmap
522
531
  #define munmap dlmunmap
@@ -526,7 +535,7 @@ static int dlmunmap(void *, size_t);
526
535
  #undef mmap
527
536
  #undef munmap
528
537
 
529
- #if !(defined(X86_WIN32) || defined(X86_WIN64) || defined(_M_ARM64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX)
538
+ #if !(defined(_WIN32) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX)
530
539
 
531
540
  /* A mutex used to synchronize access to *exec* variables in this file. */
532
541
  static pthread_mutex_t open_temp_exec_file_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -538,6 +547,17 @@ static int execfd = -1;
538
547
  /* The amount of space already allocated from the temporary file. */
539
548
  static size_t execsize = 0;
540
549
 
550
+ #ifdef HAVE_MEMFD_CREATE
551
+ /* Open a temporary file name, and immediately unlink it. */
552
+ static int
553
+ open_temp_exec_file_memfd (const char *name)
554
+ {
555
+ int fd;
556
+ fd = memfd_create (name, MFD_CLOEXEC);
557
+ return fd;
558
+ }
559
+ #endif
560
+
541
561
  /* Open a temporary file name, and immediately unlink it. */
542
562
  static int
543
563
  open_temp_exec_file_name (char *name, int flags)
@@ -665,6 +685,9 @@ static struct
665
685
  const char *arg;
666
686
  int repeat;
667
687
  } open_temp_exec_file_opts[] = {
688
+ #ifdef HAVE_MEMFD_CREATE
689
+ { open_temp_exec_file_memfd, "libffi", 0 },
690
+ #endif
668
691
  { open_temp_exec_file_env, "TMPDIR", 0 },
669
692
  { open_temp_exec_file_dir, "/tmp", 0 },
670
693
  { open_temp_exec_file_dir, "/var/tmp", 0 },
@@ -908,7 +931,7 @@ segment_holding_code (mstate m, char* addr)
908
931
  }
909
932
  #endif
910
933
 
911
- #endif /* !(defined(X86_WIN32) || defined(X86_WIN64) || defined(_M_ARM64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX) */
934
+ #endif /* !(defined(_WIN32) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX) */
912
935
 
913
936
  /* Allocate a chunk of memory with the given size. Returns a pointer
914
937
  to the writable address, and sets *CODE to the executable
@@ -921,7 +944,7 @@ ffi_closure_alloc (size_t size, void **code)
921
944
  if (!code)
922
945
  return NULL;
923
946
 
924
- ptr = dlmalloc (size);
947
+ ptr = FFI_CLOSURE_PTR (dlmalloc (size));
925
948
 
926
949
  if (ptr)
927
950
  {
@@ -961,7 +984,7 @@ ffi_closure_free (void *ptr)
961
984
  ptr = sub_segment_exec_offset (ptr, seg);
962
985
  #endif
963
986
 
964
- dlfree (ptr);
987
+ dlfree (FFI_RESTORE_PTR (ptr));
965
988
  }
966
989
 
967
990
  # else /* ! FFI_MMAP_EXEC_WRIT */
@@ -977,13 +1000,13 @@ ffi_closure_alloc (size_t size, void **code)
977
1000
  if (!code)
978
1001
  return NULL;
979
1002
 
980
- return *code = malloc (size);
1003
+ return *code = FFI_CLOSURE_PTR (malloc (size));
981
1004
  }
982
1005
 
983
1006
  void
984
1007
  ffi_closure_free (void *ptr)
985
1008
  {
986
- free (ptr);
1009
+ free (FFI_RESTORE_PTR (ptr));
987
1010
  }
988
1011
 
989
1012
  void *
@@ -0,0 +1,395 @@
1
+ /* -----------------------------------------------------------------------
2
+ ffi.c
3
+
4
+ CSKY 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
+ #include <ffi.h>
28
+ #include <ffi_common.h>
29
+
30
+ #include <stdlib.h>
31
+
32
+ /* ffi_prep_args is called by the assembly routine once stack space
33
+ has been allocated for the function's arguments
34
+ */
35
+ void ffi_prep_args(char *stack, extended_cif *ecif)
36
+ {
37
+ register unsigned int i;
38
+ register void **p_argv;
39
+ register char *argp;
40
+ register ffi_type **p_arg;
41
+
42
+ argp = stack;
43
+
44
+ if ( ecif->cif->flags == FFI_TYPE_STRUCT ) {
45
+ *(void **) argp = ecif->rvalue;
46
+ argp += 4;
47
+ }
48
+
49
+ p_argv = ecif->avalue;
50
+
51
+ for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
52
+ (i != 0);
53
+ i--, p_arg++)
54
+ {
55
+ size_t z;
56
+ size_t alignment;
57
+
58
+ /* Align if necessary */
59
+ alignment = (*p_arg)->alignment;
60
+ #ifdef __CSKYABIV1__
61
+ /*
62
+ * Adapt ABIV1 bug.
63
+ * If struct's size is larger than 8 bytes, then it always alignment as 4 bytes.
64
+ */
65
+ if (((*p_arg)->type == FFI_TYPE_STRUCT) && ((*p_arg)->size > 8) && (alignment == 8)) {
66
+ alignment = 4;
67
+ }
68
+ #endif
69
+
70
+ if ((alignment - 1) & (unsigned) argp) {
71
+ argp = (char *) FFI_ALIGN(argp, alignment);
72
+ }
73
+
74
+ if ((*p_arg)->type == FFI_TYPE_STRUCT)
75
+ argp = (char *) FFI_ALIGN(argp, 4);
76
+
77
+ z = (*p_arg)->size;
78
+ if (z < sizeof(int))
79
+ {
80
+ z = sizeof(int);
81
+ switch ((*p_arg)->type)
82
+ {
83
+ case FFI_TYPE_SINT8:
84
+ *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
85
+ break;
86
+
87
+ case FFI_TYPE_UINT8:
88
+ *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
89
+ break;
90
+
91
+ case FFI_TYPE_SINT16:
92
+ *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
93
+ break;
94
+
95
+ case FFI_TYPE_UINT16:
96
+ *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
97
+ break;
98
+
99
+ case FFI_TYPE_STRUCT:
100
+ #ifdef __CSKYBE__
101
+ memcpy((argp + 4 - (*p_arg)->size), *p_argv, (*p_arg)->size);
102
+ #else
103
+ memcpy(argp, *p_argv, (*p_arg)->size);
104
+ #endif
105
+ break;
106
+
107
+ default:
108
+ FFI_ASSERT(0);
109
+ }
110
+ }
111
+ else if (z == sizeof(int))
112
+ {
113
+ *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
114
+ }
115
+ else
116
+ {
117
+ memcpy(argp, *p_argv, z);
118
+ }
119
+ p_argv++;
120
+ argp += z;
121
+ }
122
+
123
+ return;
124
+ }
125
+
126
+ /* Perform machine dependent cif processing */
127
+ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
128
+ {
129
+ /* Round the stack up to a multiple of 8 bytes. This isn't needed
130
+ everywhere, but it is on some platforms, and it doesn't hcsky anything
131
+ when it isn't needed. */
132
+ cif->bytes = (cif->bytes + 7) & ~7;
133
+
134
+ /* Set the return type flag */
135
+ switch (cif->rtype->type)
136
+ {
137
+
138
+ case FFI_TYPE_DOUBLE:
139
+ case FFI_TYPE_SINT64:
140
+ case FFI_TYPE_UINT64:
141
+ cif->flags = (unsigned) FFI_TYPE_SINT64;
142
+ break;
143
+
144
+ case FFI_TYPE_STRUCT:
145
+ if (cif->rtype->size <= 4)
146
+ /* A Composite Type not larger than 4 bytes is returned in r0. */
147
+ cif->flags = (unsigned)FFI_TYPE_INT;
148
+ else if (cif->rtype->size <= 8)
149
+ /* A Composite Type not larger than 8 bytes is returned in r0, r1. */
150
+ cif->flags = (unsigned)FFI_TYPE_SINT64;
151
+ else
152
+ /* A Composite Type larger than 8 bytes, or whose size cannot
153
+ be determined statically ... is stored in memory at an
154
+ address passed [in r0]. */
155
+ cif->flags = (unsigned)FFI_TYPE_STRUCT;
156
+ break;
157
+
158
+ default:
159
+ cif->flags = FFI_TYPE_INT;
160
+ break;
161
+ }
162
+
163
+ return FFI_OK;
164
+ }
165
+
166
+ /* Perform machine dependent cif processing for variadic calls */
167
+ ffi_status ffi_prep_cif_machdep_var(ffi_cif *cif,
168
+ unsigned int nfixedargs,
169
+ unsigned int ntotalargs)
170
+ {
171
+ return ffi_prep_cif_machdep(cif);
172
+ }
173
+
174
+ /* Prototypes for assembly functions, in sysv.S */
175
+ extern void ffi_call_SYSV (void (*fn)(void), extended_cif *, unsigned, unsigned, unsigned *);
176
+
177
+ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
178
+ {
179
+ extended_cif ecif;
180
+
181
+ int small_struct = (cif->flags == FFI_TYPE_INT
182
+ && cif->rtype->type == FFI_TYPE_STRUCT);
183
+
184
+ ecif.cif = cif;
185
+ ecif.avalue = avalue;
186
+
187
+ unsigned int temp;
188
+
189
+ /* If the return value is a struct and we don't have a return */
190
+ /* value address then we need to make one */
191
+
192
+ if ((rvalue == NULL) &&
193
+ (cif->flags == FFI_TYPE_STRUCT))
194
+ {
195
+ ecif.rvalue = alloca(cif->rtype->size);
196
+ }
197
+ else if (small_struct)
198
+ ecif.rvalue = &temp;
199
+ else
200
+ ecif.rvalue = rvalue;
201
+
202
+ switch (cif->abi)
203
+ {
204
+ case FFI_SYSV:
205
+ ffi_call_SYSV (fn, &ecif, cif->bytes, cif->flags, ecif.rvalue);
206
+ break;
207
+
208
+ default:
209
+ FFI_ASSERT(0);
210
+ break;
211
+ }
212
+ if (small_struct)
213
+ #ifdef __CSKYBE__
214
+ memcpy (rvalue, ((unsigned char *)&temp + (4 - cif->rtype->size)), cif->rtype->size);
215
+ #else
216
+ memcpy (rvalue, &temp, cif->rtype->size);
217
+ #endif
218
+ }
219
+
220
+ /** private members **/
221
+
222
+ static void ffi_prep_incoming_args_SYSV (char *stack, void **ret,
223
+ void** args, ffi_cif* cif);
224
+
225
+ void ffi_closure_SYSV (ffi_closure *);
226
+
227
+ /* This function is jumped to by the trampoline */
228
+
229
+ unsigned int
230
+ ffi_closure_SYSV_inner (closure, respp, args)
231
+ ffi_closure *closure;
232
+ void **respp;
233
+ void *args;
234
+ {
235
+ // our various things...
236
+ ffi_cif *cif;
237
+ void **arg_area;
238
+
239
+ cif = closure->cif;
240
+ arg_area = (void**) alloca (cif->nargs * sizeof (void*));
241
+
242
+ /* this call will initialize ARG_AREA, such that each
243
+ * element in that array points to the corresponding
244
+ * value on the stack; and if the function returns
245
+ * a structure, it will re-set RESP to point to the
246
+ * structure return address. */
247
+
248
+ ffi_prep_incoming_args_SYSV(args, respp, arg_area, cif);
249
+
250
+ (closure->fun) (cif, *respp, arg_area, closure->user_data);
251
+
252
+ #ifdef __CSKYBE__
253
+ if (cif->flags == FFI_TYPE_INT && cif->rtype->type == FFI_TYPE_STRUCT) {
254
+ unsigned int tmp = 0;
255
+ tmp = *(unsigned int *)(*respp);
256
+ *(unsigned int *)(*respp) = (tmp >> ((4 - cif->rtype->size) * 8));
257
+ }
258
+ #endif
259
+
260
+ return cif->flags;
261
+ }
262
+
263
+
264
+ static void
265
+ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue,
266
+ void **avalue, ffi_cif *cif)
267
+ {
268
+ register unsigned int i;
269
+ register void **p_argv;
270
+ register char *argp;
271
+ register ffi_type **p_arg;
272
+
273
+ argp = stack;
274
+
275
+ if ( cif->flags == FFI_TYPE_STRUCT ) {
276
+ *rvalue = *(void **) argp;
277
+ argp += 4;
278
+ }
279
+
280
+ p_argv = avalue;
281
+
282
+ for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++)
283
+ {
284
+ size_t z;
285
+ size_t alignment;
286
+
287
+ alignment = (*p_arg)->alignment;
288
+ if (alignment < 4)
289
+ alignment = 4;
290
+
291
+ #ifdef __CSKYABIV1__
292
+ /*
293
+ * Adapt ABIV1 bug.
294
+ * If struct's size is larger than 8 bytes, then it always alignment as 4 bytes.
295
+ */
296
+ if (((*p_arg)->type == FFI_TYPE_STRUCT) && ((*p_arg)->size > 8) && (alignment == 8)) {
297
+ alignment = 4;
298
+ }
299
+ #endif
300
+
301
+ /* Align if necessary */
302
+ if ((alignment - 1) & (unsigned) argp) {
303
+ argp = (char *) FFI_ALIGN(argp, alignment);
304
+ }
305
+
306
+ z = (*p_arg)->size;
307
+
308
+ #ifdef __CSKYBE__
309
+ unsigned int tmp = 0;
310
+ if ((*p_arg)->size < 4) {
311
+ tmp = *(unsigned int *)argp;
312
+ memcpy(argp, ((unsigned char *)&tmp + (4 - (*p_arg)->size)), (*p_arg)->size);
313
+ }
314
+ #else
315
+ /* because we're little endian, this is what it turns into. */
316
+ #endif
317
+ *p_argv = (void*) argp;
318
+
319
+ p_argv++;
320
+ argp += z;
321
+ }
322
+
323
+ return;
324
+ }
325
+
326
+ /* How to make a trampoline. */
327
+
328
+ extern unsigned char ffi_csky_trampoline[TRAMPOLINE_SIZE];
329
+
330
+ /*
331
+ * Since there is no __clear_cache in libgcc in csky toolchain.
332
+ * define ffi_csky_cacheflush in sysv.S.
333
+ * void ffi_csky_cacheflush(uint32 start_addr, uint32 size, int cache)
334
+ */
335
+ #define CACHEFLUSH_IN_FFI 1
336
+ #if CACHEFLUSH_IN_FFI
337
+ extern void ffi_csky_cacheflush(unsigned char *__tramp, unsigned int k,
338
+ int i);
339
+ #define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX) \
340
+ ({ unsigned char *__tramp = (unsigned char*)(TRAMP); \
341
+ unsigned int __fun = (unsigned int)(FUN); \
342
+ unsigned int __ctx = (unsigned int)(CTX); \
343
+ unsigned char *insns = (unsigned char *)(CTX); \
344
+ memcpy (__tramp, ffi_csky_trampoline, TRAMPOLINE_SIZE); \
345
+ *(unsigned int*) &__tramp[TRAMPOLINE_SIZE] = __ctx; \
346
+ *(unsigned int*) &__tramp[TRAMPOLINE_SIZE + 4] = __fun; \
347
+ ffi_csky_cacheflush(&__tramp[0], TRAMPOLINE_SIZE, 3); /* Clear data mapping. */ \
348
+ ffi_csky_cacheflush(insns, TRAMPOLINE_SIZE, 3); \
349
+ /* Clear instruction \
350
+ mapping. */ \
351
+ })
352
+ #else
353
+ #define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX) \
354
+ ({ unsigned char *__tramp = (unsigned char*)(TRAMP); \
355
+ unsigned int __fun = (unsigned int)(FUN); \
356
+ unsigned int __ctx = (unsigned int)(CTX); \
357
+ unsigned char *insns = (unsigned char *)(CTX); \
358
+ memcpy (__tramp, ffi_csky_trampoline, TRAMPOLINE_SIZE); \
359
+ *(unsigned int*) &__tramp[TRAMPOLINE_SIZE] = __ctx; \
360
+ *(unsigned int*) &__tramp[TRAMPOLINE_SIZE + 4] = __fun; \
361
+ __clear_cache((&__tramp[0]), (&__tramp[TRAMPOLINE_SIZE-1])); /* Clear data mapping. */ \
362
+ __clear_cache(insns, insns + TRAMPOLINE_SIZE); \
363
+ /* Clear instruction \
364
+ mapping. */ \
365
+ })
366
+ #endif
367
+
368
+ /* the cif must already be prep'ed */
369
+
370
+ ffi_status
371
+ ffi_prep_closure_loc (ffi_closure* closure,
372
+ ffi_cif* cif,
373
+ void (*fun)(ffi_cif*,void*,void**,void*),
374
+ void *user_data,
375
+ void *codeloc)
376
+ {
377
+ void (*closure_func)(ffi_closure*) = NULL;
378
+
379
+ if (cif->abi == FFI_SYSV)
380
+ closure_func = &ffi_closure_SYSV;
381
+ else
382
+ return FFI_BAD_ABI;
383
+
384
+ FFI_INIT_TRAMPOLINE (&closure->tramp[0], \
385
+ closure_func, \
386
+ codeloc);
387
+
388
+ closure->cif = cif;
389
+ closure->user_data = user_data;
390
+ closure->fun = fun;
391
+
392
+ return FFI_OK;
393
+ }
394
+
395
+