From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 22293 invoked by alias); 13 Nov 2013 15:12:51 -0000 Mailing-List: contact libffi-discuss-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libffi-discuss-owner@sourceware.org Received: (qmail 22283 invoked by uid 89); 13 Nov 2013 15:12:50 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.2 required=5.0 tests=AWL,BAYES_50,FREEMAIL_FROM,RCVD_IN_DNSWL_NONE,RDNS_NONE,SPF_PASS autolearn=no version=3.3.2 X-HELO: mail-pd0-f178.google.com Received: from Unknown (HELO mail-pd0-f178.google.com) (209.85.192.178) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Wed, 13 Nov 2013 15:12:18 +0000 Received: by mail-pd0-f178.google.com with SMTP id p10so527559pdj.37 for ; Wed, 13 Nov 2013 07:12:10 -0800 (PST) X-Received: by 10.66.140.40 with SMTP id rd8mr42922926pab.119.1384355530685; Wed, 13 Nov 2013 07:12:10 -0800 (PST) Received: from bubble.grove.modra.org ([101.166.26.37]) by mx.google.com with ESMTPSA id vk17sm52407661pab.5.2013.11.13.07.12.09 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 13 Nov 2013 07:12:10 -0800 (PST) Received: by bubble.grove.modra.org (Postfix, from userid 1000) id 192D4EA006D; Thu, 14 Nov 2013 01:42:06 +1030 (CST) Date: Wed, 13 Nov 2013 15:12:00 -0000 From: Alan Modra To: libffi-discuss@sourceware.org Subject: libffi testsuite fixes for big-endian Message-ID: <20131113151205.GA20756@bubble.grove.modra.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) X-SW-Source: 2013/txt/msg00199.txt.bz2 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