Fix large struct passing on PA-RISC
authorAnthony Green <green@moxielogic.com>
Sun, 20 Nov 2022 17:20:40 +0000 (12:20 -0500)
committerAnthony Green <green@moxielogic.com>
Sun, 20 Nov 2022 17:20:40 +0000 (12:20 -0500)
src/pa/ffi.c

index 95e669473e1ecda58a1d5f50e05b7b132b414b5c..186bf694738bad5a8b6a32fe2654e18a04be985e 100644 (file)
@@ -376,10 +376,26 @@ extern void ffi_call_pa32(void (*)(UINT32 *, extended_cif *, unsigned),
 void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
 {
   extended_cif ecif;
+  size_t i, nargs = cif->nargs;
+  ffi_type **arg_types = cif->arg_types;
 
   ecif.cif = cif;
   ecif.avalue = avalue;
 
+  /* If we have any large structure arguments, make a copy so we are passing
+     by value.  */
+  for (i = 0; i < nargs; i++)
+    {
+      ffi_type *at = arg_types[i];
+      int size = at->size;
+      if (at->type == FFI_TYPE_STRUCT && size > 8)
+       {
+         char *argcopy = alloca (size);
+         memcpy (argcopy, avalue[i], size);
+         avalue[i] = argcopy;
+       }
+    }
+
   /* If the return value is a struct and we don't have a return
      value address then we need to make one.  */