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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +82 -0
- data/Gemfile +4 -2
- data/README.md +10 -2
- data/Rakefile +31 -43
- data/ext/ffi_c/AbstractMemory.c +24 -25
- data/ext/ffi_c/Buffer.c +4 -9
- data/ext/ffi_c/Call.c +3 -14
- data/ext/ffi_c/ClosurePool.c +75 -25
- data/ext/ffi_c/ClosurePool.h +3 -1
- data/ext/ffi_c/DynamicLibrary.c +1 -6
- data/ext/ffi_c/Function.c +15 -35
- data/ext/ffi_c/FunctionInfo.c +3 -8
- data/ext/ffi_c/LastError.c +2 -6
- data/ext/ffi_c/LongDouble.c +5 -3
- data/ext/ffi_c/LongDouble.h +0 -4
- data/ext/ffi_c/MemoryPointer.c +3 -8
- data/ext/ffi_c/MethodHandle.c +21 -31
- data/ext/ffi_c/MethodHandle.h +3 -2
- data/ext/ffi_c/Platform.c +3 -7
- data/ext/ffi_c/Pointer.c +25 -26
- data/ext/ffi_c/Struct.c +3 -6
- data/ext/ffi_c/StructByValue.c +2 -7
- data/ext/ffi_c/StructLayout.c +9 -7
- data/ext/ffi_c/Thread.c +0 -8
- data/ext/ffi_c/Thread.h +1 -9
- data/ext/ffi_c/Type.c +1 -1
- data/ext/ffi_c/Variadic.c +2 -7
- data/ext/ffi_c/compat.h +4 -0
- data/ext/ffi_c/extconf.rb +33 -23
- data/ext/ffi_c/libffi/.travis.yml +4 -0
- data/ext/ffi_c/libffi/.travis/bfin-sim.exp +1 -1
- data/ext/ffi_c/libffi/.travis/build.sh +4 -0
- data/ext/ffi_c/libffi/.travis/m32r-sim.exp +1 -1
- data/ext/ffi_c/libffi/.travis/moxie-sim.exp +1 -1
- data/ext/ffi_c/libffi/.travis/or1k-sim.exp +1 -1
- data/ext/ffi_c/libffi/.travis/powerpc-eabisim.exp +1 -1
- data/ext/ffi_c/libffi/.travis/wine-sim.exp +1 -1
- data/ext/ffi_c/libffi/Makefile.am +49 -58
- data/ext/ffi_c/libffi/README.md +11 -1
- data/ext/ffi_c/libffi/config.guess +552 -331
- data/ext/ffi_c/libffi/config.sub +1321 -1306
- data/ext/ffi_c/libffi/configure.ac +31 -10
- data/ext/ffi_c/libffi/configure.host +32 -20
- data/ext/ffi_c/libffi/doc/Makefile.am +3 -0
- data/ext/ffi_c/libffi/doc/libffi.texi +997 -0
- data/ext/ffi_c/libffi/doc/version.texi +4 -0
- data/ext/ffi_c/libffi/generate-darwin-source-and-headers.py +1 -1
- data/ext/ffi_c/libffi/include/ffi.h.in +8 -0
- data/ext/ffi_c/libffi/libffi.map.in +8 -12
- data/ext/ffi_c/libffi/libtool-version +1 -1
- data/ext/ffi_c/libffi/msvcc.sh +11 -11
- data/ext/ffi_c/libffi/src/aarch64/ffi.c +51 -35
- data/ext/ffi_c/libffi/src/aarch64/ffitarget.h +10 -5
- data/ext/ffi_c/libffi/src/aarch64/internal.h +1 -0
- data/ext/ffi_c/libffi/src/aarch64/sysv.S +14 -3
- data/ext/ffi_c/libffi/src/aarch64/win64_armasm.S +1 -1
- data/ext/ffi_c/libffi/src/arm/ffi.c +22 -0
- data/ext/ffi_c/libffi/src/arm/sysv.S +4 -4
- data/ext/ffi_c/libffi/src/closures.c +33 -10
- data/ext/ffi_c/libffi/src/csky/ffi.c +395 -0
- data/ext/ffi_c/libffi/src/csky/ffitarget.h +63 -0
- data/ext/ffi_c/libffi/src/csky/sysv.S +371 -0
- data/ext/ffi_c/libffi/src/dlmalloc.c +1 -1
- data/ext/ffi_c/libffi/src/kvx/asm.h +5 -0
- data/ext/ffi_c/libffi/src/kvx/ffi.c +273 -0
- data/ext/ffi_c/libffi/src/kvx/ffitarget.h +75 -0
- data/ext/ffi_c/libffi/src/kvx/sysv.S +127 -0
- data/ext/ffi_c/libffi/src/mips/ffi.c +5 -1
- data/ext/ffi_c/libffi/src/mips/ffitarget.h +1 -1
- data/ext/ffi_c/libffi/src/pa/ffi.c +46 -91
- data/ext/ffi_c/libffi/src/pa/ffitarget.h +1 -6
- data/ext/ffi_c/libffi/src/pa/hpux32.S +4 -2
- data/ext/ffi_c/libffi/src/pa/linux.S +4 -2
- data/ext/ffi_c/libffi/src/powerpc/ffi_darwin.c +13 -1
- data/ext/ffi_c/libffi/src/powerpc/ffi_powerpc.h +1 -1
- data/ext/ffi_c/libffi/src/powerpc/linux64.S +8 -0
- data/ext/ffi_c/libffi/src/powerpc/linux64_closure.S +13 -1
- data/ext/ffi_c/libffi/src/powerpc/sysv.S +5 -7
- data/ext/ffi_c/libffi/src/prep_cif.c +1 -1
- data/ext/ffi_c/libffi/src/x86/ffi.c +15 -6
- data/ext/ffi_c/libffi/src/x86/ffi64.c +17 -8
- data/ext/ffi_c/libffi/src/x86/ffitarget.h +15 -2
- data/ext/ffi_c/libffi/src/x86/ffiw64.c +15 -8
- data/ext/ffi_c/libffi/src/x86/sysv.S +15 -6
- data/ext/ffi_c/libffi/src/x86/unix64.S +59 -4
- data/ext/ffi_c/libffi/src/x86/win64.S +7 -3
- data/ext/ffi_c/libffi/src/x86/win64_intel.S +3 -2
- data/ext/ffi_c/libffi/testsuite/lib/libffi.exp +22 -2
- data/ext/ffi_c/libffi/testsuite/libffi.bhaible/test-call.c +4 -4
- data/ext/ffi_c/libffi/testsuite/libffi.bhaible/test-callback.c +2 -2
- data/ext/ffi_c/libffi/testsuite/libffi.closures/huge_struct.c +2 -0
- data/ffi.gemspec +2 -2
- data/lib/ffi.rb +10 -2
- data/lib/ffi/abstract_memory.rb +44 -0
- data/lib/ffi/autopointer.rb +1 -1
- data/lib/ffi/ffi.rb +1 -0
- data/lib/ffi/io.rb +3 -3
- data/lib/ffi/library.rb +6 -2
- data/lib/ffi/managedstruct.rb +2 -2
- data/lib/ffi/platform.rb +21 -8
- data/lib/ffi/platform/aarch64-darwin/types.conf +130 -0
- data/lib/ffi/platform/aarch64-openbsd/types.conf +134 -0
- data/lib/ffi/platform/arm-linux/types.conf +32 -4
- data/lib/ffi/platform/i386-windows/types.conf +26 -79
- data/lib/ffi/platform/powerpc-linux/types.conf +32 -2
- data/lib/ffi/platform/powerpc-openbsd/types.conf +156 -0
- data/lib/ffi/platform/sparcv9-openbsd/types.conf +156 -0
- data/lib/ffi/platform/x86_64-darwin/types.conf +4 -0
- data/lib/ffi/platform/x86_64-dragonflybsd/types.conf +4 -22
- data/lib/ffi/platform/x86_64-haiku/types.conf +117 -0
- data/lib/ffi/platform/x86_64-linux/types.conf +21 -0
- data/lib/ffi/platform/x86_64-msys/types.conf +119 -0
- data/lib/ffi/platform/x86_64-windows/types.conf +10 -78
- data/lib/ffi/pointer.rb +21 -14
- data/lib/ffi/struct.rb +8 -2
- data/lib/ffi/tools/types_generator.rb +2 -0
- data/lib/ffi/variadic.rb +1 -1
- data/lib/ffi/version.rb +1 -1
- data/samples/getlogin.rb +1 -1
- data/samples/getpid.rb +1 -1
- data/samples/gettimeofday.rb +8 -8
- data/samples/hello.rb +2 -1
- data/samples/inotify.rb +1 -1
- data/samples/pty.rb +1 -2
- data/samples/qsort.rb +0 -1
- metadata +18 -12
- data/.appveyor.yml +0 -27
- data/.gitignore +0 -25
- data/.gitmodules +0 -4
- data/.travis.yml +0 -44
- data/.yardopts +0 -5
- data/ext/ffi_c/win32/stdbool.h +0 -8
- data/ext/ffi_c/win32/stdint.h +0 -201
- 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, [
|
|
133
|
-
vldmgt
|
|
132
|
+
vldrle d0, [r0]
|
|
133
|
+
vldmgt r0, {d0-d7}
|
|
134
134
|
#else
|
|
135
|
-
ldcle p11, cr0, [r0] @ vldrle d0, [
|
|
136
|
-
ldcgt p11, cr0, [r0], {16} @ vldmgt
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
+
|