From fcbf63e62c627deae76c1b8cb8c0876c536ed811 Mon Sep 17 00:00:00 2001 From: Jari Vetoniemi Date: Mon, 16 Mar 2020 18:49:26 +0900 Subject: Fresh start --- jni/ruby/ext/fiddle/libffi-3.2.1/src/vax/elfbsd.S | 195 +++++++++++++++ jni/ruby/ext/fiddle/libffi-3.2.1/src/vax/ffi.c | 276 +++++++++++++++++++++ .../ext/fiddle/libffi-3.2.1/src/vax/ffitarget.h | 49 ++++ 3 files changed, 520 insertions(+) create mode 100644 jni/ruby/ext/fiddle/libffi-3.2.1/src/vax/elfbsd.S create mode 100644 jni/ruby/ext/fiddle/libffi-3.2.1/src/vax/ffi.c create mode 100644 jni/ruby/ext/fiddle/libffi-3.2.1/src/vax/ffitarget.h (limited to 'jni/ruby/ext/fiddle/libffi-3.2.1/src/vax') diff --git a/jni/ruby/ext/fiddle/libffi-3.2.1/src/vax/elfbsd.S b/jni/ruby/ext/fiddle/libffi-3.2.1/src/vax/elfbsd.S new file mode 100644 index 0000000..01ca313 --- /dev/null +++ b/jni/ruby/ext/fiddle/libffi-3.2.1/src/vax/elfbsd.S @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2013 Miodrag Vallat. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * ``Software''), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * vax Foreign Function Interface + */ + +#define LIBFFI_ASM +#include +#include + + .text + +/* + * void * %r0 + * ffi_call_elfbsd(extended_cif *ecif, 4(%ap) + * unsigned bytes, 8(%ap) + * unsigned flags, 12(%ap) + * void *rvalue, 16(%ap) + * void (*fn)()); 20(%ap) + */ + .globl ffi_call_elfbsd + .type ffi_call_elfbsd,@function + .align 2 +ffi_call_elfbsd: + .word 0x00c # save R2 and R3 + + # Allocate stack space for the args + subl2 8(%ap), %sp + + # Call ffi_prep_args + pushl %sp + pushl 4(%ap) + calls $2, ffi_prep_args + + # Get function pointer + movl 20(%ap), %r1 + + # Build a CALLS frame + ashl $-2, 8(%ap), %r0 + pushl %r0 # argument stack usage + movl %sp, %r0 # future %ap + # saved registers + bbc $11, 0(%r1), 1f + pushl %r11 +1: bbc $10, 0(%r1), 1f + pushl %r10 +1: bbc $9, 0(%r1), 1f + pushl %r9 +1: bbc $8, 0(%r1), 1f + pushl %r8 +1: bbc $7, 0(%r1), 1f + pushl %r7 +1: bbc $6, 0(%r1), 1f + pushl %r6 +1: bbc $5, 0(%r1), 1f + pushl %r5 +1: bbc $4, 0(%r1), 1f + pushl %r4 +1: bbc $3, 0(%r1), 1f + pushl %r3 +1: bbc $2, 0(%r1), 1f + pushl %r2 +1: + pushal 9f + pushl %fp + pushl %ap + movl 16(%ap), %r3 # struct return address, if needed + movl %r0, %ap + movzwl 4(%fp), %r0 # previous PSW, without the saved registers mask + bisl2 $0x20000000, %r0 # calls frame + movzwl 0(%r1), %r2 + bicw2 $0xf003, %r2 # only keep R11-R2 + ashl $16, %r2, %r2 + bisl2 %r2, %r0 # saved register mask of the called function + pushl %r0 + pushl $0 + movl %sp, %fp + + # Invoke the function + pushal 2(%r1) # skip procedure entry mask + movl %r3, %r1 + bicpsw $0x000f + rsb + +9: + # Copy return value if necessary + tstl 16(%ap) + jeql 9f + movl 16(%ap), %r2 + + bbc $0, 12(%ap), 1f # CIF_FLAGS_CHAR + movb %r0, 0(%r2) + brb 9f +1: + bbc $1, 12(%ap), 1f # CIF_FLAGS_SHORT + movw %r0, 0(%r2) + brb 9f +1: + bbc $2, 12(%ap), 1f # CIF_FLAGS_INT + movl %r0, 0(%r2) + brb 9f +1: + bbc $3, 12(%ap), 1f # CIF_FLAGS_DINT + movq %r0, 0(%r2) + brb 9f +1: + movl %r1, %r0 # might have been a struct + #brb 9f + +9: + ret + +/* + * ffi_closure_elfbsd(void); + * invoked with %r0: ffi_closure *closure + */ + .globl ffi_closure_elfbsd + .type ffi_closure_elfbsd, @function + .align 2 +ffi_closure_elfbsd: + .word 0 + + # Allocate room on stack for return value + subl2 $8, %sp + + # Invoke the closure function + pushal 4(%ap) # calling stack + pushal 4(%sp) # return value + pushl %r0 # closure + calls $3, ffi_closure_elfbsd_inner + + # Copy return value if necessary + bitb $1, %r0 # CIF_FLAGS_CHAR + beql 1f + movb 0(%sp), %r0 + brb 9f +1: + bitb $2, %r0 # CIF_FLAGS_SHORT + beql 1f + movw 0(%sp), %r0 + brb 9f +1: + bitb $4, %r0 # CIF_FLAGS_INT + beql 1f + movl 0(%sp), %r0 + brb 9f +1: + bitb $8, %r0 # CIF_FLAGS_DINT + beql 1f + movq 0(%sp), %r0 + #brb 9f +1: + +9: + ret + +/* + * ffi_closure_struct_elfbsd(void); + * invoked with %r0: ffi_closure *closure + * %r1: struct return address + */ + .globl ffi_closure_struct_elfbsd + .type ffi_closure_struct_elfbsd, @function + .align 2 +ffi_closure_struct_elfbsd: + .word 0 + + # Invoke the closure function + pushal 4(%ap) # calling stack + pushl %r1 # return value + pushl %r0 # closure + calls $3, ffi_closure_elfbsd_inner + + ret diff --git a/jni/ruby/ext/fiddle/libffi-3.2.1/src/vax/ffi.c b/jni/ruby/ext/fiddle/libffi-3.2.1/src/vax/ffi.c new file mode 100644 index 0000000..f4d6bbb --- /dev/null +++ b/jni/ruby/ext/fiddle/libffi-3.2.1/src/vax/ffi.c @@ -0,0 +1,276 @@ +/* + * Copyright (c) 2013 Miodrag Vallat. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * ``Software''), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * vax Foreign Function Interface + * + * This file attempts to provide all the FFI entry points which can reliably + * be implemented in C. + */ + +#include +#include + +#include +#include + +#define CIF_FLAGS_CHAR 1 /* for struct only */ +#define CIF_FLAGS_SHORT 2 /* for struct only */ +#define CIF_FLAGS_INT 4 +#define CIF_FLAGS_DINT 8 + +/* + * Foreign Function Interface API + */ + +void ffi_call_elfbsd (extended_cif *, unsigned, unsigned, void *, + void (*) ()); +void *ffi_prep_args (extended_cif *ecif, void *stack); + +void * +ffi_prep_args (extended_cif *ecif, void *stack) +{ + unsigned int i; + void **p_argv; + char *argp; + ffi_type **p_arg; + void *struct_value_ptr; + + argp = stack; + + if (ecif->cif->rtype->type == FFI_TYPE_STRUCT + && !ecif->cif->flags) + struct_value_ptr = ecif->rvalue; + else + struct_value_ptr = NULL; + + p_argv = ecif->avalue; + + for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; + i != 0; + i--, p_arg++) + { + size_t z; + + z = (*p_arg)->size; + if (z < sizeof (int)) + { + switch ((*p_arg)->type) + { + case FFI_TYPE_SINT8: + *(signed int *) argp = (signed int) *(SINT8 *) *p_argv; + break; + + case FFI_TYPE_UINT8: + *(unsigned int *) argp = (unsigned int) *(UINT8 *) *p_argv; + break; + + case FFI_TYPE_SINT16: + *(signed int *) argp = (signed int) *(SINT16 *) *p_argv; + break; + + case FFI_TYPE_UINT16: + *(unsigned int *) argp = (unsigned int) *(UINT16 *) *p_argv; + break; + + case FFI_TYPE_STRUCT: + memcpy (argp, *p_argv, z); + break; + + default: + FFI_ASSERT (0); + } + z = sizeof (int); + } + else + { + memcpy (argp, *p_argv, z); + + /* Align if necessary. */ + if ((sizeof(int) - 1) & z) + z = ALIGN(z, sizeof(int)); + } + + p_argv++; + argp += z; + } + + return struct_value_ptr; +} + +ffi_status +ffi_prep_cif_machdep (ffi_cif *cif) +{ + /* Set the return type flag */ + switch (cif->rtype->type) + { + case FFI_TYPE_VOID: + cif->flags = 0; + break; + + case FFI_TYPE_STRUCT: + if (cif->rtype->elements[0]->type == FFI_TYPE_STRUCT && + cif->rtype->elements[1]) + { + cif->flags = 0; + break; + } + + if (cif->rtype->size == sizeof (char)) + cif->flags = CIF_FLAGS_CHAR; + else if (cif->rtype->size == sizeof (short)) + cif->flags = CIF_FLAGS_SHORT; + else if (cif->rtype->size == sizeof (int)) + cif->flags = CIF_FLAGS_INT; + else if (cif->rtype->size == 2 * sizeof (int)) + cif->flags = CIF_FLAGS_DINT; + else + cif->flags = 0; + break; + + default: + if (cif->rtype->size <= sizeof (int)) + cif->flags = CIF_FLAGS_INT; + else + cif->flags = CIF_FLAGS_DINT; + break; + } + + return FFI_OK; +} + +void +ffi_call (ffi_cif *cif, void (*fn) (), void *rvalue, void **avalue) +{ + extended_cif ecif; + + ecif.cif = cif; + ecif.avalue = avalue; + + /* If the return value is a struct and we don't have a return value + address then we need to make one. */ + + if (rvalue == NULL + && cif->rtype->type == FFI_TYPE_STRUCT + && cif->flags == 0) + ecif.rvalue = alloca (cif->rtype->size); + else + ecif.rvalue = rvalue; + + switch (cif->abi) + { + case FFI_ELFBSD: + ffi_call_elfbsd (&ecif, cif->bytes, cif->flags, ecif.rvalue, fn); + break; + + default: + FFI_ASSERT (0); + break; + } +} + +/* + * Closure API + */ + +void ffi_closure_elfbsd (void); +void ffi_closure_struct_elfbsd (void); +unsigned int ffi_closure_elfbsd_inner (ffi_closure *, void *, char *); + +static void +ffi_prep_closure_elfbsd (ffi_cif *cif, void **avalue, char *stackp) +{ + unsigned int i; + void **p_argv; + ffi_type **p_arg; + + p_argv = avalue; + + for (i = cif->nargs, p_arg = cif->arg_types; i != 0; i--, p_arg++) + { + size_t z; + + z = (*p_arg)->size; + *p_argv = stackp; + + /* Align if necessary */ + if ((sizeof (int) - 1) & z) + z = ALIGN(z, sizeof (int)); + + p_argv++; + stackp += z; + } +} + +unsigned int +ffi_closure_elfbsd_inner (ffi_closure *closure, void *resp, char *stack) +{ + ffi_cif *cif; + void **arg_area; + + cif = closure->cif; + arg_area = (void **) alloca (cif->nargs * sizeof (void *)); + + ffi_prep_closure_elfbsd (cif, arg_area, stack); + + (closure->fun) (cif, resp, arg_area, closure->user_data); + + return cif->flags; +} + +ffi_status +ffi_prep_closure_loc (ffi_closure *closure, ffi_cif *cif, + void (*fun)(ffi_cif *, void *, void **, void *), + void *user_data, void *codeloc) +{ + char *tramp = (char *) codeloc; + void *fn; + + FFI_ASSERT (cif->abi == FFI_ELFBSD); + + /* entry mask */ + *(unsigned short *)(tramp + 0) = 0x0000; + /* movl #closure, r0 */ + tramp[2] = 0xd0; + tramp[3] = 0x8f; + *(unsigned int *)(tramp + 4) = (unsigned int) closure; + tramp[8] = 0x50; + + if (cif->rtype->type == FFI_TYPE_STRUCT + && !cif->flags) + fn = &ffi_closure_struct_elfbsd; + else + fn = &ffi_closure_elfbsd; + + /* jmpl #fn */ + tramp[9] = 0x17; + tramp[10] = 0xef; + *(unsigned int *)(tramp + 11) = (unsigned int)fn + 2 - + (unsigned int)tramp - 9 - 6; + + closure->cif = cif; + closure->user_data = user_data; + closure->fun = fun; + + return FFI_OK; +} diff --git a/jni/ruby/ext/fiddle/libffi-3.2.1/src/vax/ffitarget.h b/jni/ruby/ext/fiddle/libffi-3.2.1/src/vax/ffitarget.h new file mode 100644 index 0000000..2fc9488 --- /dev/null +++ b/jni/ruby/ext/fiddle/libffi-3.2.1/src/vax/ffitarget.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2013 Miodrag Vallat. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * ``Software''), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * vax Foreign Function Interface + */ + +#ifndef LIBFFI_TARGET_H +#define LIBFFI_TARGET_H + +#ifndef LIBFFI_ASM +typedef unsigned long ffi_arg; +typedef signed long ffi_sarg; + +typedef enum ffi_abi { + FFI_FIRST_ABI = 0, + FFI_ELFBSD, + FFI_DEFAULT_ABI = FFI_ELFBSD, + FFI_LAST_ABI = FFI_DEFAULT_ABI + 1 +} ffi_abi; +#endif + +/* ---- Definitions for closures ----------------------------------------- */ + +#define FFI_CLOSURES 1 +#define FFI_TRAMPOLINE_SIZE 15 +#define FFI_NATIVE_RAW_API 0 + +#endif -- cgit v1.2.3