libffi: Fix 32-bit SPARC structure passing [PR115681]

Message ID yddsewt5w69.fsf@CeBiTec.Uni-Bielefeld.DE
State Committed
Commit 61aa380bad45fb070379f259f7abc5e5f50c9009
Headers
Series libffi: Fix 32-bit SPARC structure passing [PR115681] |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gcc_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 fail Patch failed to apply
linaro-tcwg-bot/tcwg_gcc_check--master-arm fail Patch failed to apply

Commit Message

Rainer Orth July 1, 2024, 8:54 a.m. UTC
  The libffi.closures/single_entry_structs2.c test FAILs on 32-bit SPARC:

FAIL: libffi.closures/single_entry_structs2.c -W -Wall -Wno-psabi -O0 execution test

The issue has been reported, analyzed and fixed upstream:

	Several tests FAIL on 32-bit Solaris/SPARC
	https://github.com/libffi/libffi/issues/841

Therefore this patch imports the fix into the GCC tree.

Tested on sparc-sun-solaris2.11.  Ok for trunk?

	Rainer
  

Comments

Eric Botcazou July 1, 2024, 9:06 a.m. UTC | #1
> The issue has been reported, analyzed and fixed upstream:
> 
> 	Several tests FAIL on 32-bit Solaris/SPARC
> 	https://github.com/libffi/libffi/issues/841
> 
> Therefore this patch imports the fix into the GCC tree.
> 
> Tested on sparc-sun-solaris2.11.  Ok for trunk?

Sure, thanks!
  

Patch

# HG changeset patch
# Parent  31401e58fa469c62c2278e38d35817fab3407e97
libffi: Fix 32-bit SPARC structure passing

diff --git a/libffi/src/sparc/ffi.c b/libffi/src/sparc/ffi.c
--- a/libffi/src/sparc/ffi.c
+++ b/libffi/src/sparc/ffi.c
@@ -286,6 +286,8 @@  ffi_call_int (ffi_cif *cif, void (*fn)(v
 	      void **avalue, void *closure)
 {
   size_t bytes = cif->bytes;
+  size_t i, nargs = cif->nargs;
+  ffi_type **arg_types = cif->arg_types;
 
   FFI_ASSERT (cif->abi == FFI_V8);
 
@@ -295,6 +297,20 @@  ffi_call_int (ffi_cif *cif, void (*fn)(v
       && (cif->flags & SPARC_FLAG_RET_MASK) == SPARC_RET_STRUCT)
     bytes += FFI_ALIGN (cif->rtype->size, 8);
 
+  /* If we have any 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)
+        {
+          char *argcopy = alloca (size);
+          memcpy (argcopy, avalue[i], size);
+          avalue[i] = argcopy;
+        }
+    }
+
   ffi_call_v8(cif, fn, rvalue, avalue, -bytes, closure);
 }