Bug#1024492: libffi: large structs need to be passed by value on hppa
Source: libffi
Version: 3.2.1-9
Severity: normal
Tags: patch
Dear Maintainer,
The following tests fail on hppa:
=== libffi tests ===
Schedule of variations:
unix
Running target unix
Using /usr/share/dejagnu/baseboards/unix.exp as board description file for target.
Using /usr/share/dejagnu/config/unix.exp as generic interface file for target.
Using ../../testsuite/config/default.exp as tool-and-target-specific interface file.
Running ../../testsuite/libffi.bhaible/bhaible.exp ...
Running ../../testsuite/libffi.call/call.exp ...
FAIL: libffi.call/struct_by_value_3.c -W -Wall -Wno-psabi -O0 execution test
FAIL: libffi.call/struct_by_value_3.c -W -Wall -Wno-psabi -O2 execution test
FAIL: libffi.call/struct_by_value_4.c -W -Wall -Wno-psabi -O0 execution test
FAIL: libffi.call/struct_by_value_4.c -W -Wall -Wno-psabi -O2 execution test
FAIL: libffi.call/struct_by_value_big.c -W -Wall -Wno-psabi -O0 execution test
FAIL: libffi.call/struct_by_value_big.c -W -Wall -Wno-psabi -O2 execution test
Running ../../testsuite/libffi.closures/closure.exp ...
Running ../../testsuite/libffi.complex/complex.exp ...
Running ../../testsuite/libffi.go/go.exp ...
=== libffi Summary ===
# of expected passes 1482
# of unexpected failures 6
# of unsupported tests 30
make[3]: *** [Makefile:466: check-DEJAGNU] Error 1
Full log is here:
https://buildd.debian.org/status/fetch.php?pkg=libffi&arch=hppa&ver=3.4.4-1&stamp=1666606326&raw=0
This is upstream issue #749:
https://github.com/libffi/libffi/issues/749
Attached is patch to fix the problem on hppa. It is similar to patch
applied to fix issue on sparc64.
Please apply until issue is fixed in upstream source.
Regards,
Dave Anglin
-- System Information:
Debian Release: bookworm/sid
APT prefers buildd-unstable
APT policy: (500, 'buildd-unstable'), (500, 'unstable')
Architecture: hppa (parisc64)
Kernel: Linux 6.0.9 (SMP w/4 CPU threads)
Locale: LANG=C, LC_CTYPE=C.UTF-8 (charmap=UTF-8), LANGUAGE not set
Shell: /bin/sh linked to /usr/bin/dash
Init: systemd (via /run/systemd/system)
diff --git a/src/pa/ffi.c b/src/pa/ffi.c
index 95e6694..186bf69 100644
--- a/src/pa/ffi.c
+++ b/src/pa/ffi.c
@@ -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. */
Reply to: