From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: <382-725-6798@kylheku.com> Received: from smtp-out-so.shaw.ca (smtp-out-so.shaw.ca [64.59.136.139]) by sourceware.org (Postfix) with ESMTPS id 7312E383542D for ; Thu, 10 Jun 2021 02:05:28 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 7312E383542D Received: from kylheku.com ([70.79.163.252]) by shaw.ca with ESMTPA id rA4TlfWDA7YjPrA4UlWeu2; Wed, 09 Jun 2021 20:05:27 -0600 X-Authority-Analysis: v=2.4 cv=fPVaYbWe c=1 sm=1 tr=0 ts=60c17367 a=95A0EdhkF1LMGt25d7h1IQ==:117 a=95A0EdhkF1LMGt25d7h1IQ==:17 a=IkcTkHD0fZMA:10 a=SMorJkV_YP8A:10 a=r6YtysWOX24A:10 a=JRgdxxy3AAAA:20 a=E7xb329eftlyViDfMEYA:9 a=QEXdDO2ut3YA:10 a=Oj-nxcKMq9sL0NVIgHWn:22 Received: from www-data by kylheku.com with local (Exim 4.72) (envelope-from <382-725-6798@kylheku.com>) id 1lrA4S-0003BI-SR; Wed, 09 Jun 2021 19:05:24 -0700 To: Cheng Jin Subject: Re: Incorrect data detected in the nested float struct with x86/libffi on Linux/64bit X-PHP-Originating-Script: 501:rcmail.php MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: quoted-printable Date: Wed, 09 Jun 2021 19:05:24 -0700 From: "Kaz Kylheku (libffi)" <382-725-6798@kylheku.com> Cc: libffi-discuss@sourceware.org In-Reply-To: References: Message-ID: X-Sender: 382-725-6798@kylheku.com User-Agent: Roundcube Webmail/0.9.2 X-CMAE-Envelope: MS4xfAtMfdRwkwK8X7DbZnNeoaqdBxufULPUQIx2Ij+RRVbWQwEKyROeXLyI6MDLNI9p+YITVWzTOVyitMs19GYe5x2Q8I1Ppi41kk+Tqzoenh1ttI+dQPSq xHxYRLvsUqpiK3IGyTywi8dkEDxgshj3IpDzZQWFJ+DrY3oRRnkEyDGG4ax7ESw6xczDs4OQ6BMRi5ErglfCL2pxiMhTwuWkyarleQrkm4uDfJer886QY9x/ X-Spam-Status: No, score=-2.5 required=5.0 tests=BAYES_00, FROM_STARTS_WITH_NUMS, KAM_DMARC_STATUS, RCVD_IN_DNSWL_LOW, 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: Thu, 10 Jun 2021 02:05:30 -0000 On 2021-06-09 09:41, Cheng Jin via Libffi-discuss wrote: > Hi, >=20 > We found that the nested struct [[float, float], float] works good with > x86/libffi (at https://github.com/libffi/libffi/tree/master/src/x86) > on Linux/64bit (verified on Ubuntu 19) while a variant of it like > [float,[float,float]] was messed up at the 3rd element when invoking > ffi_call() in the following test: In the libffi that comes with Ubuntu 18.04 Server, x84-64, your test case aborts in ffi_call. I built a similar test case in which I put your function into a shared lib, and used a libffi-based programming language to call it. Same thing: abort in ffi_call. There is some problem in that version of libffi; it doesn't like small structures. If I add padding to the structure, then there is no abort. My version of the function looks like this: float_t testNestedFloatStruct(float_t arg1, stru_Nested_F arg2) { float_t floatSum =3D arg1 + arg2.elem1 + arg2.elem2.elem1 +=20 arg2.elem2.elem2; puts("called"); printf("arg1 =3D %f, arg2 =3D { %f, { %f, %f } }\n", arg1, arg2.elem1, arg2.elem2.elem1, arg2.elem2.elem2); return floatSum; } On the FFI side, if I add a uint64's worth of padding to the structure, the ffi_call proceeds without abort, and the result is like this: arg1 =3D 1.000000, arg2 =3D { 0.000000, { 0.000000,=20 -52784298695107543040.000000 } } -5.27842986951075e19 The second line is the caller printing the return value. As you can see, complete rubbish. If I take out the padding and change everything to double (my float_f typedef lets me do that easily), it looks like this: arg1 =3D 1.000000, arg2 =3D { 2.000000, { 3.000000, 4.000000 } } 10.0 That's the expected behavior; the all-float case should look the same. Basically with the padding, although the call works, it's using the=20 wrong calling conventions. I think this small structure is supposed to be=20 passed in registers. If I step over the ffi_prep_cif call to see what args were passed to it and how the sizes and alignment were set, all looks good: ffi_make_call_desc (ntotal=3D, nfixed=3D, rettype=3D0x7ffff7f97780, argtypes=3D, name_in=3D) at ffi.c:4831 4831 if (ffis !=3D FFI_OK) (gdb) p args[0] $5 =3D (ffi_type *) 0x758c80 (gdb) p args[1] $6 =3D (ffi_type *) 0xc38220 (gdb) p (*args[1]) $7 =3D {size =3D 12, alignment =3D 4, type =3D 13, elements =3D 0xc38240} (gdb) p (*args[1]).elements[0] $8 =3D (struct _ffi_type *) 0x758c80 (gdb) p (*args[1]).elements[1] $9 =3D (struct _ffi_type *) 0xb92160 (gdb) p (*(*args[1]).elements[1]) $10 =3D {size =3D 8, alignment =3D 4, type =3D 13, elements =3D 0xb92180} (gdb) p (*(*args[1]).elements[1]).elements[0] $11 =3D (struct _ffi_type *) 0x758c80 (gdb) p (*(*args[1]).elements[1]).elements[1] $12 =3D (struct _ffi_type *) 0x758c80 (gdb) p (*(*args[1]).elements[1]).elements[2] $13 =3D (struct _ffi_type *) 0x0 (gdb) p (*args[1]).elements[2] $14 =3D (struct _ffi_type *) 0x0 Both elements arrays have two elements and a null terminator. Two floats at the leaves, and a float + struct at the first level.