From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 9690 invoked by alias); 23 Oct 2013 18:27:08 -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 9676 invoked by uid 89); 23 Oct 2013 18:27:07 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=AWL,BAYES_00 autolearn=ham version=3.3.2 X-HELO: world.peace.net Received: from world.peace.net (HELO world.peace.net) (96.39.62.75) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-SHA encrypted) ESMTPS; Wed, 23 Oct 2013 18:27:06 +0000 Received: from 209-6-91-212.c3-0.smr-ubr1.sbo-smr.ma.cable.rcn.com ([209.6.91.212] helo=yeeloong) by world.peace.net with esmtpsa (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.72) (envelope-from ) id 1VZ38y-0000GR-8M; Wed, 23 Oct 2013 14:26:56 -0400 From: Mark H Weaver To: libffi-discuss@sourceware.org Subject: [PATCH] Fix handling of uint32_t arguments on the MIPS N32 ABI. Date: Wed, 23 Oct 2013 18:27:00 -0000 Message-ID: <87fvrrzvws.fsf@netris.org> MIME-Version: 1.0 Content-Type: text/plain X-SW-Source: 2013/txt/msg00192.txt.bz2 Hello all, A failing glib test on MIPS N32 has alerted me to a bug in the handling of unsigned 32-bit integers in libffi. The MIPSpro N32 ABI Handbook [*] states: "32-bit integer (int) parameters are always sign-extended when passed in registers, whether of signed or unsigned type. [This issue does not arise in the o32-bit ABI.]" (chapter 2, page 6) [*] http://techpubs.sgi.com/library/manuals/2000/007-2816-005/pdf/007-2816-005.pdf and indeed GCC generates code that assumes this. For example, GCC 4.7.3 compiles: --8<---------------cut here---------------start------------->8--- #include #include void do_test (uint32_t a) { if (a != 4294967253U) exit (1); } --8<---------------cut here---------------end--------------->8--- as follows (with extraneous cruft stripped): --8<---------------cut here---------------start------------->8--- do_test: li $2,-43 # 0xffffffffffffffd5 beq $4,$2,.L5 nop addiu $sp,$sp,-16 sd $31,8($sp) jal exit li $4,1 # 0x1 .L5: j $31 nop --8<---------------cut here---------------end--------------->8--- However, the current libffi code zero-extends 32-bit unsigned integers, which violates this N32 FFI requirement. See below for a patch to fix this problem. I've tested this patch on the preliminary port of GNU Guix to MIPS N32, which uses a minimally patched GNU toolchain targetting mips64el-linux-gnu. Without this patch, glib-2.38.0 fails its test suite, specifically the gobject/test/signal.c test, which uses libffi to pass a large 32-bit unsigned integer to a test function that checks the received value. With this patch, glib-2.38.0 passes its test suite. Comments and suggestions welcome. Regards, Mark Signed-off-by: Mark H Weaver --- ChangeLog | 5 +++++ src/mips/ffi.c | 7 +++++++ 2 files changed, 12 insertions(+), 0 deletions(-) diff --git a/ChangeLog b/ChangeLog index eceef84..e7e5d94 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-10-23 Mark H Weaver + + * src/mips/ffi.c: Fix handling of uint32_t arguments on the + MIPS N32 ABI. + 2013-10-13 Sandra Loosemore * README: Add Nios II to table of supported platforms. diff --git a/src/mips/ffi.c b/src/mips/ffi.c index 03121e3..5d0dd70 100644 --- a/src/mips/ffi.c +++ b/src/mips/ffi.c @@ -170,7 +170,14 @@ static void ffi_prep_args(char *stack, break; case FFI_TYPE_UINT32: +#ifdef FFI_MIPS_N32 + /* The N32 ABI requires that 32-bit integers + be sign-extended to 64-bits, regardless of + whether they are signed or unsigned. */ + *(ffi_arg *)argp = *(SINT32 *)(* p_argv); +#else *(ffi_arg *)argp = *(UINT32 *)(* p_argv); +#endif break; /* This can only happen with 64bit slots. */ -- 1.7.5.4