This is the mail archive of the libffi-discuss@sourceware.org mailing list for the libffi project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

libffi testsuite fixes for big-endian


Most of the libffi testsuite uses ffi_arg for return values.  A few
tests don't, and don't use a return type that is the same size as
ffi_arg on powerpc64.  This means the wrong bytes are written, giving
spurious failures.

To clarify what is going on here, consider a testcase like
closure_fn1.c.  closure_test_fn1 takes a void* "resp" return value
pointer, and writes the return with *(ffi_arg*)resp = expression,
despite ffi_prep_cif being told the return type is ffi_type_sint.
ffi_arg is a 64-bit integer type on powerpc64, while int is 32-bit.
This means the glue code in ffi_closure_LINUX64 and
ffi_closure_helper_LINUX64 must allocate a 64-bit buffer to hold the
return value, and retrieve the low int part (byte offset 4) from that
location to place in the return value register, r3.  A closure
function like the one in cls_struct_va1.c that writes *(int *)resp
will put the return value at offset 0 in this buffer.

A similar situation exists with ffi_call return values.

It would be possible to write the glue code to handle the real return
types, as suggested by examples in the documentation, but you'd need
to do that for all targets, and update the testsuite to avoid
ffi_arg..  That might be a worthy goal but for now we ought to be
consistent in the testsuite.

	* libffi.call/cls_struct_va1.c (test_fn): Return value is ffi_arg*.
	* libffi.call/cls_uint_va.c (cls_ret_T_fn): Likewise.
	* libffi.call/va_1.c (main): Make res an ffi_arg.
	* libffi.call/va_struct1.c (main): Likewise.

diff --git a/testsuite/libffi.call/cls_struct_va1.c b/testsuite/libffi.call/cls_struct_va1.c
index 175ed96..9c4be7f 100644
--- a/testsuite/libffi.call/cls_struct_va1.c
+++ b/testsuite/libffi.call/cls_struct_va1.c
@@ -35,7 +35,7 @@ test_fn (ffi_cif* cif __UNUSED__, void* resp,
   printf ("%d %d %d %d %d %d %d %d %d %d\n", n, s1.a, s1.b,
 	  l1.a, l1.b, l1.c, l1.d, l1.e,
 	  s2.a, s2.b);
-  * (int*) resp = 42;
+  *(ffi_arg *) resp = 42;
 }
 
 int
diff --git a/testsuite/libffi.call/cls_uint_va.c b/testsuite/libffi.call/cls_uint_va.c
index 150fddd..584a3e1 100644
--- a/testsuite/libffi.call/cls_uint_va.c
+++ b/testsuite/libffi.call/cls_uint_va.c
@@ -13,9 +13,9 @@ typedef unsigned int T;
 static void cls_ret_T_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
 			 void* userdata __UNUSED__)
  {
-   *(T *)resp = *(T *)args[0];
+   *(ffi_arg *)resp = *(T *)args[0];
 
-   printf("%d: %d %d\n", *(T *)resp, *(T *)args[0], *(T *)args[1]);
+   printf("%d: %d %d\n", (T) *(ffi_arg *)resp, *(T *)args[0], *(T *)args[1]);
  }
 
 typedef T (*cls_ret_T)(T, ...);
diff --git a/testsuite/libffi.call/va_1.c b/testsuite/libffi.call/va_1.c
index cf4dd85..7f96809 100644
--- a/testsuite/libffi.call/va_1.c
+++ b/testsuite/libffi.call/va_1.c
@@ -94,7 +94,7 @@ main (void)
   struct large_tag l1;
 
   int n;
-  int res;
+  ffi_arg res;
 
   unsigned char uc;
   signed char sc;
diff --git a/testsuite/libffi.call/va_struct1.c b/testsuite/libffi.call/va_struct1.c
index 11d1f10..e645206 100644
--- a/testsuite/libffi.call/va_struct1.c
+++ b/testsuite/libffi.call/va_struct1.c
@@ -61,7 +61,7 @@ main (void)
   struct large_tag l1;
 
   int n;
-  int res;
+  ffi_arg res;
 
   s_type.size = 0;
   s_type.alignment = 0;

-- 
Alan Modra
Australia Development Lab, IBM


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]