Skip to content

Commit

Permalink
Merge pull request #19645 from r30shah/fix_libffi_struct
Browse files Browse the repository at this point in the history
Add support for FFI_TYPE_STRUCT_FF/DD on z/OS
  • Loading branch information
keithc-ca authored Jul 11, 2024
2 parents 5a03e1a + b73b7f3 commit 66f477d
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 168 deletions.
24 changes: 13 additions & 11 deletions runtime/libffi/preconf/mz64/ffi.h
Original file line number Diff line number Diff line change
Expand Up @@ -466,18 +466,18 @@ void ffi_call(ffi_cif *cif,

#if !defined(ZOS)
/* If these change, update src/mips/ffitarget.h. */
#define FFI_TYPE_VOID 0
#define FFI_TYPE_VOID 0
#define FFI_TYPE_INT 1
#define FFI_TYPE_FLOAT 2
#define FFI_TYPE_FLOAT 2
#define FFI_TYPE_DOUBLE 3
#if 1
#define FFI_TYPE_LONGDOUBLE 4
#else
#define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE
#endif
#define FFI_TYPE_UINT8 5
#define FFI_TYPE_UINT8 5
#define FFI_TYPE_SINT8 6
#define FFI_TYPE_UINT16 7
#define FFI_TYPE_UINT16 7
#define FFI_TYPE_SINT16 8
#define FFI_TYPE_UINT32 9
#define FFI_TYPE_SINT32 10
Expand All @@ -495,23 +495,25 @@ void ffi_call(ffi_cif *cif,
#else
#define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE
#endif
#define FFI_TYPE_UINT8 3
#define FFI_TYPE_UINT8 3
#define FFI_TYPE_SINT8 4
#define FFI_TYPE_UINT16 5
#define FFI_TYPE_UINT16 5
#define FFI_TYPE_SINT16 6
#define FFI_TYPE_UINT32 7
#define FFI_TYPE_SINT64 8
#define FFI_TYPE_POINTER 9
#define FFI_TYPE_SINT64 8
#define FFI_TYPE_POINTER 9
#define FFI_TYPE_UINT64 10
#define FFI_TYPE_FLOAT 11
#define FFI_TYPE_FLOAT 11
#define FFI_TYPE_STRUCT 12
#define FFI_TYPE_VOID 13
#define FFI_TYPE_VOID 13
#define FFI_TYPE_SINT32 14
#define FFI_TYPE_COMPLEX 15
#define FFI_TYPE_STRUCT_FF 16
#define FFI_TYPE_STRUCT_DD 17
#endif

/* This should always refer to the last type code (for sanity checks) */
#define FFI_TYPE_LAST FFI_TYPE_COMPLEX
#define FFI_TYPE_LAST FFI_TYPE_STRUCT_DD

#ifdef __cplusplus
}
Expand Down
50 changes: 49 additions & 1 deletion runtime/libffi/z/ffi64.c
Original file line number Diff line number Diff line change
Expand Up @@ -699,6 +699,8 @@ ffi_prep_args (unsigned char *stack, extended_cif *ecif)
switch (type)
{
case FFI_TYPE_STRUCT:
case FFI_TYPE_STRUCT_FF:
case FFI_TYPE_STRUCT_DD:
memcpy(arg_ptr, *p_argv, size);
break;

Expand Down Expand Up @@ -766,6 +768,50 @@ ffi_prep_args (unsigned char *stack, extended_cif *ecif)

/*======================== End of Routine ============================*/

/**
* Helper functions to know if the given struct needs to be treated for complex
* type for float or double.
*/
static unsigned short
get_ffi_element_type_in_struct(ffi_type *arg_type)
{
while ((FFI_TYPE_STRUCT == arg_type->type)
&& (NULL != arg_type->elements[0])
&& (NULL == arg_type->elements[1])
) {
arg_type = arg_type->elements[0];
}
return arg_type->type;
}

static unsigned short
ffi_check_struct_for_complex(ffi_type *arg_type)
{
if ((FFI_TYPE_STRUCT == arg_type->type) && (NULL != arg_type->elements[0]))
{
unsigned short firstArgType = get_ffi_element_type_in_struct(arg_type->elements[0]);
if (FFI_TYPE_FLOAT == firstArgType)
{
if ((NULL != arg_type->elements[1])
&& (NULL == arg_type->elements[2])
&& (FFI_TYPE_FLOAT == get_ffi_element_type_in_struct(arg_type->elements[1]))
) {
return FFI_TYPE_STRUCT_FF;
}
}
else if (FFI_TYPE_DOUBLE == firstArgType)
{
if ((NULL != arg_type->elements[1])
&& (NULL == arg_type->elements[2])
&& (FFI_TYPE_DOUBLE == get_ffi_element_type_in_struct(arg_type->elements[1]))
) {
return FFI_TYPE_STRUCT_DD;
}
}
}
return arg_type->type;
}

/*====================================================================*/
/* */
/* Name - ffi_prep_cif_machdep. */
Expand Down Expand Up @@ -861,7 +907,7 @@ ffi_prep_cif_machdep(ffi_cif *cif)
FFI_ASSERT (0);
break;
}

cif->rtype->type = ffi_check_struct_for_complex(cif->rtype);
/* Now for the arguments. */

for (ptr = cif->arg_types, i = cif->nargs;
Expand All @@ -875,6 +921,8 @@ ffi_prep_cif_machdep(ffi_cif *cif)
{
type = ffi_check_struct_type (*ptr);

(*ptr)->type = ffi_check_struct_for_complex(*ptr);

/* If we pass the struct via pointer, we must reserve space
to copy its data for proper call-by-value semantics. */
if (type == FFI_TYPE_POINTER)
Expand Down
Loading

0 comments on commit 66f477d

Please sign in to comment.