From patchwork Thu Sep 16 14:03:20 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 64977 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 8668D1007DB for ; Fri, 17 Sep 2010 00:02:41 +1000 (EST) Received: (qmail 5015 invoked by alias); 16 Sep 2010 14:02:38 -0000 Received: (qmail 5002 invoked by uid 22791); 16 Sep 2010 14:02:37 -0000 X-SWARE-Spam-Status: No, hits=-6.1 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, SPF_HELO_PASS, TW_BF, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 16 Sep 2010 14:02:30 +0000 Received: from int-mx03.intmail.prod.int.phx2.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o8GE2SbQ029535 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Thu, 16 Sep 2010 10:02:28 -0400 Received: from tyan-ft48-01.lab.bos.redhat.com (tyan-ft48-01.lab.bos.redhat.com [10.16.42.4]) by int-mx03.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o8GE2RTb027037 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Thu, 16 Sep 2010 10:02:28 -0400 Received: from tyan-ft48-01.lab.bos.redhat.com (tyan-ft48-01.lab.bos.redhat.com [127.0.0.1]) by tyan-ft48-01.lab.bos.redhat.com (8.14.4/8.14.4) with ESMTP id o8GE3KDT028843; Thu, 16 Sep 2010 16:03:20 +0200 Received: (from jakub@localhost) by tyan-ft48-01.lab.bos.redhat.com (8.14.4/8.14.4/Submit) id o8GE3Kdj028842; Thu, 16 Sep 2010 16:03:20 +0200 Date: Thu, 16 Sep 2010 16:03:20 +0200 From: Jakub Jelinek To: Anthony Green , Tom Tromey Cc: gcc-patches@gcc.gnu.org Subject: [PATCH] Fix libffi x86-64 < 8 bytes last stack argument issue (PR libffi/45677) Message-ID: <20100916140320.GR1269@tyan-ft48-01.lab.bos.redhat.com> Reply-To: Jakub Jelinek MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.20 (2009-12-10) X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Hi! GCC assumes the callee owns the whole stack slot word instead of just the first 8/16/32 bits of it when the last argument is 8/16/32 bit. unix64.S puts a saved copy of flags right after the last byte of the arguments block, so when it was not a multiple of 8 bytes, GCC could happily clobber the saved copy of flags after it. Fixed thusly, tested on x86_64-linux, ok to commit? 2010-09-16 Jakub Jelinek PR libffi/45677 * src/x86/ffi64.c (ffi_prep_cif_machdep): Ensure cif->bytes is a multiple of 8. * testsuite/libffi.call/many2.c: New test. Jakub --- libffi/src/x86/ffi64.c.jj 2010-08-11 21:08:14.000000000 +0200 +++ libffi/src/x86/ffi64.c 2010-09-16 15:34:57.000000000 +0200 @@ -378,7 +378,7 @@ ffi_prep_cif_machdep (ffi_cif *cif) if (align < 8) align = 8; - bytes = ALIGN(bytes, align); + bytes = ALIGN (bytes, align); bytes += cif->arg_types[i]->size; } else @@ -390,7 +390,7 @@ ffi_prep_cif_machdep (ffi_cif *cif) if (ssecount) flags |= 1 << 11; cif->flags = flags; - cif->bytes = bytes; + cif->bytes = ALIGN (bytes, 8); return FFI_OK; } --- libffi/testsuite/libffi.call/many2.c.jj 2010-09-16 15:01:08.000000000 +0200 +++ libffi/testsuite/libffi.call/many2.c 2010-09-16 15:28:57.000000000 +0200 @@ -0,0 +1,54 @@ +/* Area: ffi_call + Purpose: Check uint8_t arguments. + Limitations: none. + PR: PR45677. + Originator: Dan Witte 20100916 */ + +/* { dg-do run } */ + +#include "ffitest.h" + +#define NARGS 7 + +typedef unsigned char u8; + +__attribute__((noinline)) uint8_t +foo (uint8_t a, uint8_t b, uint8_t c, uint8_t d, + uint8_t e, uint8_t f, uint8_t g) +{ + return a + b + c + d + e + f + g; +} + +uint8_t +bar (uint8_t a, uint8_t b, uint8_t c, uint8_t d, + uint8_t e, uint8_t f, uint8_t g) +{ + return foo (a, b, c, d, e, f, g); +} + +int +main (void) +{ + ffi_type *ffitypes[NARGS]; + int i; + ffi_cif cif; + ffi_arg result = 0; + uint8_t args[NARGS]; + void *argptrs[NARGS]; + + for (i = 0; i < NARGS; ++i) + ffitypes[i] = &ffi_type_uint8; + + CHECK (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, NARGS, + &ffi_type_uint8, ffitypes) == FFI_OK); + + for (i = 0; i < NARGS; ++i) + { + args[i] = i; + argptrs[i] = &args[i]; + } + ffi_call (&cif, FFI_FN (bar), &result, argptrs); + + CHECK (result == 21); + return 0; +}