Kaz Kylheku (libffi)
2017-05-27 16:59:36 UTC
Hi all,
My interpreted language's test suite failed on a PPC64 Linux box
(gcc110.fsffrance.org).
The test in question uses the qsort C library function to sort a Lisp
vector, using a Lisp callback.
Unfortunately, the int return value from the callback turns to garbage.
The problem reproduces with current libffi from git.
The following test patch makes the problem go away and all tests pass:
diff --git a/src/powerpc/linux64_closure.S
b/src/powerpc/linux64_closure.S
index 6487d2a..28a191a 100644
--- a/src/powerpc/linux64_closure.S
+++ b/src/powerpc/linux64_closure.S
@@ -27,7 +27,8 @@
#define LIBFFI_ASM
#include <fficonfig.h>
#include <ffi.h>
-
+#undef __LITTLE_ENDIAN__
+#define __LITTLE_ENDIAN__ 1
.file "linux64_closure.S"
#ifdef POWERPC64
The problem is that all the big endian cases are expecting the caller to
place the return value at a displaced address. If the type is int, for
instance, the expectation is that the return value is to be stored at
*(int *)(retval + 4). If it is short, then at *(short *)(retval + 6)
and so on.
Is this documented somewhere?
My code is storing everything at just the retval base address,
regardless of size.
Cheers ...
My interpreted language's test suite failed on a PPC64 Linux box
(gcc110.fsffrance.org).
The test in question uses the qsort C library function to sort a Lisp
vector, using a Lisp callback.
Unfortunately, the int return value from the callback turns to garbage.
The problem reproduces with current libffi from git.
The following test patch makes the problem go away and all tests pass:
diff --git a/src/powerpc/linux64_closure.S
b/src/powerpc/linux64_closure.S
index 6487d2a..28a191a 100644
--- a/src/powerpc/linux64_closure.S
+++ b/src/powerpc/linux64_closure.S
@@ -27,7 +27,8 @@
#define LIBFFI_ASM
#include <fficonfig.h>
#include <ffi.h>
-
+#undef __LITTLE_ENDIAN__
+#define __LITTLE_ENDIAN__ 1
.file "linux64_closure.S"
#ifdef POWERPC64
The problem is that all the big endian cases are expecting the caller to
place the return value at a displaced address. If the type is int, for
instance, the expectation is that the return value is to be stored at
*(int *)(retval + 4). If it is short, then at *(short *)(retval + 6)
and so on.
Is this documented somewhere?
My code is storing everything at just the retval base address,
regardless of size.
Cheers ...