From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [216.205.24.124]) by sourceware.org (Postfix) with ESMTP id CCF2B3857413 for ; Tue, 15 Jun 2021 18:03:04 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org CCF2B3857413 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-517-Rz-bVyVWNV6pwqXQeIovNQ-1; Tue, 15 Jun 2021 14:03:01 -0400 X-MC-Unique: Rz-bVyVWNV6pwqXQeIovNQ-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id E5DFE1923764; Tue, 15 Jun 2021 18:03:00 +0000 (UTC) Received: from tucnak.zalov.cz (ovpn-112-7.ams2.redhat.com [10.36.112.7]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 9047C60C0F; Tue, 15 Jun 2021 18:03:00 +0000 (UTC) Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.16.1/8.16.1) with ESMTPS id 15FI2vc83067159 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Tue, 15 Jun 2021 20:02:57 +0200 Received: (from jakub@localhost) by tucnak.zalov.cz (8.16.1/8.16.1/Submit) id 15FI2uYd3067158; Tue, 15 Jun 2021 20:02:56 +0200 Date: Tue, 15 Jun 2021 20:02:56 +0200 From: Jakub Jelinek To: Anthony Green Cc: Cheng Jin , libffi-discuss , DJ Delorie Subject: Re: Incorrect data detected in the nested float struct with x86/libffi on Linux/64bit Message-ID: <20210615180256.GQ7746@tucnak> Reply-To: Jakub Jelinek References: MIME-Version: 1.0 In-Reply-To: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=us-ascii Content-Disposition: inline X-Spam-Status: No, score=-5.8 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, KAM_SHORT, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libffi-discuss@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libffi-discuss mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 15 Jun 2021 18:03:07 -0000 On Wed, Jun 09, 2021 at 12:50:08PM -0400, Anthony Green wrote: > Thank you, Cheng. Are you able to submit this test case as a github pull > request? The resulting CI testing will give us a broader picture of where > we have problems. Comparing gcc/config/i386/ classify_argument and libffi classify_argument, I found two important differences. The first one seems the most important one, even GCC 3.2 included the bit offset (byte offset in libffi) in the calculation of number of words. And the other change is https://gcc.gnu.org/PR38781. With this patch the posted testcase works and the testsuite on x86_64-linux still passes, but haven't done more testing than that. Haven't tried yet to adapt one of the libffi/testsuite/libffi.call/nested_struct*.c tests to cover this though. 2021-06-15 Jakub Jelinek * src/x86/ffi64.c (classify_argument): For FFI_TYPE_STRUCT set words to number of words needed for type->size + byte_offset bytes rather than just type->size bytes. Compute pos before the loop and check total size of the structure. --- libffi/src/x86/ffi64.c.jj 2020-01-14 20:02:48.557583260 +0100 +++ libffi/src/x86/ffi64.c 2021-06-15 19:50:06.059108230 +0200 @@ -217,7 +217,8 @@ classify_argument (ffi_type *type, enum case FFI_TYPE_STRUCT: { const size_t UNITS_PER_WORD = 8; - size_t words = (type->size + UNITS_PER_WORD - 1) / UNITS_PER_WORD; + size_t words = (type->size + byte_offset + UNITS_PER_WORD - 1) + / UNITS_PER_WORD; ffi_type **ptr; int i; enum x86_64_reg_class subclasses[MAX_CLASSES]; @@ -241,16 +242,16 @@ classify_argument (ffi_type *type, enum /* Merge the fields of structure. */ for (ptr = type->elements; *ptr != NULL; ptr++) { - size_t num; + size_t num, pos; byte_offset = ALIGN (byte_offset, (*ptr)->alignment); num = classify_argument (*ptr, subclasses, byte_offset % 8); if (num == 0) return 0; - for (i = 0; i < num; i++) + pos = byte_offset / 8; + for (i = 0; i < num && (i + pos) < words; i++) { - size_t pos = byte_offset / 8; classes[i + pos] = merge_classes (subclasses[i], classes[i + pos]); } Jakub