public inbox for libffi-discuss@sourceware.org
 help / color / mirror / Atom feed
From: "Cheng Jin" <jincheng@ca.ibm.com>
To: "Kaz Kylheku (libffi)" <382-725-6798@kylheku.com>
Cc: libffi-discuss@sourceware.org
Subject: RE: Incorrect data detected in the nested float struct with x86/libffi on Linux/64bit
Date: Wed, 9 Jun 2021 22:39:00 -0400	[thread overview]
Message-ID: <OF02C799C9.BD590CCF-ON002586F0.000CC4E5-852586F0.000E8ED7@ibm.com> (raw)
In-Reply-To: <cb87f420e998ab562dac048fb6dbc957@mail.kylheku.com>

[-- Attachment #1: Type: text/plain, Size: 4266 bytes --]




Hi Kaz,

It is highly likely that the version of libffi coming with Ubuntu 18 is
outdated (we experienced the same abort with an outdated x86/libffi
integrated in our own project).
Please try the latest version of x86/libffi at
https://github.com/libffi/libffi/tree/master/src/x86.

In addition, adding padding to the nested structure might work but doesn't
make any sense as ffi_prep_cif() will detect/compute the padding
automatically in the code, in which case everything related to padding
should be handled by libffi rather than by users. That's why they need to
investigate why it failed to handle on Linux/64bit given it works good on
other platforms (e.g. Windows/x86_64, Aarch64).


Thanks and Best Regards
Cheng Jin




From:	"Kaz Kylheku (libffi)" <382-725-6798@kylheku.com>
To:	Cheng Jin <jincheng@ca.ibm.com>
Cc:	libffi-discuss@sourceware.org
Date:	2021-06-09 10:05 PM
Subject:	[EXTERNAL] Re: Incorrect data detected in the nested float
            struct with  x86/libffi on Linux/64bit



On 2021-06-09 09:41, Cheng Jin via Libffi-discuss wrote:
> Hi,
>
> 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 = arg1 + arg2.elem1 + arg2.elem2.elem1 +
arg2.elem2.elem2;
   puts("called");
   printf("arg1 = %f, arg2 = { %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 = 1.000000, arg2 = { 0.000000, { 0.000000,
-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 = 1.000000, arg2 = { 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
wrong
calling conventions. I think this small structure is supposed to be
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=<optimized out>, nfixed=<optimized out>,
     rettype=0x7ffff7f97780, argtypes=<optimized out>, name_in=<optimized
out>)
     at ffi.c:4831
4831      if (ffis != FFI_OK)
(gdb) p args[0]
$5 = (ffi_type *) 0x758c80 <ffi_type_float>
(gdb) p args[1]
$6 = (ffi_type *) 0xc38220
(gdb) p (*args[1])
$7 = {size = 12, alignment = 4, type = 13, elements = 0xc38240}
(gdb) p (*args[1]).elements[0]
$8 = (struct _ffi_type *) 0x758c80 <ffi_type_float>
(gdb) p (*args[1]).elements[1]
$9 = (struct _ffi_type *) 0xb92160
(gdb) p (*(*args[1]).elements[1])
$10 = {size = 8, alignment = 4, type = 13, elements = 0xb92180}
(gdb) p (*(*args[1]).elements[1]).elements[0]
$11 = (struct _ffi_type *) 0x758c80 <ffi_type_float>
(gdb) p (*(*args[1]).elements[1]).elements[1]
$12 = (struct _ffi_type *) 0x758c80 <ffi_type_float>
(gdb) p (*(*args[1]).elements[1]).elements[2]
$13 = (struct _ffi_type *) 0x0
(gdb) p (*args[1]).elements[2]
$14 = (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.




[-- Attachment #2: graycol.gif --]
[-- Type: image/gif, Size: 105 bytes --]

      reply	other threads:[~2021-06-10  2:39 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-09 16:41 Cheng Jin
2021-06-09 16:50 ` Anthony Green
2021-06-09 17:53   ` Cheng Jin
2021-06-15 18:02   ` Jakub Jelinek
2021-06-15 19:02     ` Jakub Jelinek
2021-06-15 19:29       ` Anthony Green
2021-06-09 23:48 ` Kaz Kylheku (libffi)
2021-06-10  0:21   ` Cheng Jin
2021-06-10  2:05 ` Kaz Kylheku (libffi)
2021-06-10  2:39   ` Cheng Jin [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=OF02C799C9.BD590CCF-ON002586F0.000CC4E5-852586F0.000E8ED7@ibm.com \
    --to=jincheng@ca.ibm.com \
    --cc=382-725-6798@kylheku.com \
    --cc=libffi-discuss@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).