* Incorrect data detected in the nested float struct with x86/libffi on Linux/64bit
@ 2021-06-09 16:41 Cheng Jin
2021-06-09 16:50 ` Anthony Green
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: Cheng Jin @ 2021-06-09 16:41 UTC (permalink / raw)
To: libffi-discuss
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:
typedef struct stru_Nested_F stru_Nested_F;
struct stru_FF {
float elem1;
float elem2;
};
struct stru_Nested_F {
float elem1;
stru_FF elem2;
};
static float testNestedFloatStruct(float arg1, stru_Nested_F arg2)
{
float floatSum = arg1 + arg2.elem1 + arg2.elem2.elem1 +
arg2.elem2.elem2;
return floatSum;
}
int main() {
float returnValue = 0;
ffi_cif cif_temp;
UDATA structElemNum = 2;
UDATA nestedStructElemNum = 2;
UDATA argNum = 2;
ffi_type **cls_struct_fields1 = (ffi_type **)malloc(sizeof(ffi_type
*) * (structElemNum + 1));
ffi_type **cls_struct_fields2 = (ffi_type **)malloc(sizeof(ffi_type
*) * (nestedStructElemNum + 1));
ffi_type **dbl_arg_types = (ffi_type **)malloc(sizeof(ffi_type *) *
(argNum + 1));
void **args_db = (void **)malloc(sizeof(void *) * (argNum + 1));
ffi_type cls_struct_type1, cls_struct_type2;
ffi_type *retType = &ffi_type_float;
float arg1;
float *arg2 = (float *)malloc(sizeof(stru_Nested_F));
cls_struct_fields2[0] = &ffi_type_float;
cls_struct_fields2[1] = &ffi_type_float;
cls_struct_fields2[2] = NULL;
cls_struct_type2.size = 0;
cls_struct_type2.alignment = 0;
cls_struct_type2.type = FFI_TYPE_STRUCT;
cls_struct_type2.elements = cls_struct_fields2;
cls_struct_fields1[0] = &ffi_type_float;
cls_struct_fields1[1] = &cls_struct_type2;
cls_struct_fields1[2] = NULL;
cls_struct_type1.size = 0;
cls_struct_type1.alignment = 0;
cls_struct_type1.type = FFI_TYPE_STRUCT;
cls_struct_type1.elements = cls_struct_fields1;
dbl_arg_types[0] = &ffi_type_float;
dbl_arg_types[1] = &cls_struct_type1;
dbl_arg_types[2] = NULL;
ffi_prep_cif(&cif_temp, FFI_DEFAULT_ABI, 2, retType, dbl_arg_types);
arg1 = 37.88;
arg2[0] = 31.22;
arg2[1] = 33.44;
arg2[2] = 35.66;
args_db[0] = &arg1;
args_db[1] = arg2;
args_db[2] = NULL;
ffi_call(&cif_temp, FFI_FN(testNestedFloatStruct), &returnValue,
args_db);
free(cls_struct_fields1);
free(cls_struct_fields2);
free(dbl_arg_types);
free(args_db);
return 0;
}
with the debugging output as follows:
(gdb) p arg2[0]
$1 = 31.2199993
(gdb) p arg2[1]
$2 = 33.4399986
(gdb) p arg2[2]
$3 = 35.6599998
(gdb) x/10x arg2
0x7ffff025b540: 0x41f9c28f 0x4205c28f 0x420ea3d7 0xdddddddd
0x7ffff025b550: 0xb7654321 0x475d4352 0x0000000c 0x00000000
0x7ffff025b560: 0xf749c970 0x00007fff
(gdb) bt
#0 testNestedFloatStruct(arg1=37.8800011, arg2=...) at main.c:xxx
#1 0x00007ffff746e4e0 in ffi_call_unix64 () at x86/unix64.S:xxx
#2 0x00007ffff746dac8 in ffi_call (cif=0x7ffff7d44e90, fn=0x7ffff7f9e060,
rvalue=0x16818, avalue=0x7ffff7d44f30) at x86/ffi64.c:xxx
Thread 2 "main" hit Breakpoint 2, testNestedFloatStruct(arg1=37.8800011,
arg2=...) at main.c
float floatSum = arg1 + arg2.elem1 + arg2.elem2.elem1 +
arg2.elem2.elem2;
(gdb) p arg2
$4 = {
elem1 = 31.2199993,
elem2 = {
elem1 = 33.4399986,
elem2 = 4.20389539e-45 <------------------ messed up
}
}
(gdb) x/10x &arg2
0x7ffff7d44458: 0x41f9c28f 0x4205c28f 0x00000003 0x00007fff
0x7ffff7d44468: 0xf70cf1e6 0x4217851f 0xf7d44510 0x00007fff
0x7ffff7d44478: 0xf7d44660 0x00007fff
-------------------------------------------
It looks like there is something wrong in dealing with the nested stuct on
Linux/64bit in x86/libffi as the test above works good on Windows/64bit.
Thanks and Best Regards
Cheng Jin
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Incorrect data detected in the nested float struct with x86/libffi on Linux/64bit
2021-06-09 16:41 Incorrect data detected in the nested float struct with x86/libffi on Linux/64bit 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-09 23:48 ` Kaz Kylheku (libffi)
2021-06-10 2:05 ` Kaz Kylheku (libffi)
2 siblings, 2 replies; 10+ messages in thread
From: Anthony Green @ 2021-06-09 16:50 UTC (permalink / raw)
To: Cheng Jin; +Cc: libffi-discuss
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.
Thanks,
AG
On Wed, Jun 9, 2021 at 12:41 PM Cheng Jin via Libffi-discuss <
libffi-discuss@sourceware.org> 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:
>
>
> typedef struct stru_Nested_F stru_Nested_F;
>
> struct stru_FF {
> float elem1;
> float elem2;
> };
>
> struct stru_Nested_F {
> float elem1;
> stru_FF elem2;
> };
>
> static float testNestedFloatStruct(float arg1, stru_Nested_F arg2)
> {
> float floatSum = arg1 + arg2.elem1 + arg2.elem2.elem1 +
> arg2.elem2.elem2;
> return floatSum;
> }
>
> int main() {
> float returnValue = 0;
> ffi_cif cif_temp;
> UDATA structElemNum = 2;
> UDATA nestedStructElemNum = 2;
> UDATA argNum = 2;
> ffi_type **cls_struct_fields1 = (ffi_type
> **)malloc(sizeof(ffi_type
> *) * (structElemNum + 1));
> ffi_type **cls_struct_fields2 = (ffi_type
> **)malloc(sizeof(ffi_type
> *) * (nestedStructElemNum + 1));
> ffi_type **dbl_arg_types = (ffi_type **)malloc(sizeof(ffi_type
> *) *
> (argNum + 1));
> void **args_db = (void **)malloc(sizeof(void *) * (argNum + 1));
> ffi_type cls_struct_type1, cls_struct_type2;
> ffi_type *retType = &ffi_type_float;
> float arg1;
> float *arg2 = (float *)malloc(sizeof(stru_Nested_F));
>
> cls_struct_fields2[0] = &ffi_type_float;
> cls_struct_fields2[1] = &ffi_type_float;
> cls_struct_fields2[2] = NULL;
>
> cls_struct_type2.size = 0;
> cls_struct_type2.alignment = 0;
> cls_struct_type2.type = FFI_TYPE_STRUCT;
> cls_struct_type2.elements = cls_struct_fields2;
>
> cls_struct_fields1[0] = &ffi_type_float;
> cls_struct_fields1[1] = &cls_struct_type2;
> cls_struct_fields1[2] = NULL;
>
> cls_struct_type1.size = 0;
> cls_struct_type1.alignment = 0;
> cls_struct_type1.type = FFI_TYPE_STRUCT;
> cls_struct_type1.elements = cls_struct_fields1;
>
> dbl_arg_types[0] = &ffi_type_float;
> dbl_arg_types[1] = &cls_struct_type1;
> dbl_arg_types[2] = NULL;
>
> ffi_prep_cif(&cif_temp, FFI_DEFAULT_ABI, 2, retType,
> dbl_arg_types);
> arg1 = 37.88;
> arg2[0] = 31.22;
> arg2[1] = 33.44;
> arg2[2] = 35.66;
> args_db[0] = &arg1;
> args_db[1] = arg2;
> args_db[2] = NULL;
>
> ffi_call(&cif_temp, FFI_FN(testNestedFloatStruct), &returnValue,
> args_db);
>
> free(cls_struct_fields1);
> free(cls_struct_fields2);
> free(dbl_arg_types);
> free(args_db);
>
> return 0;
> }
>
> with the debugging output as follows:
>
> (gdb) p arg2[0]
> $1 = 31.2199993
> (gdb) p arg2[1]
> $2 = 33.4399986
> (gdb) p arg2[2]
> $3 = 35.6599998
> (gdb) x/10x arg2
> 0x7ffff025b540: 0x41f9c28f 0x4205c28f 0x420ea3d7 0xdddddddd
> 0x7ffff025b550: 0xb7654321 0x475d4352 0x0000000c 0x00000000
> 0x7ffff025b560: 0xf749c970 0x00007fff
>
>
> (gdb) bt
> #0 testNestedFloatStruct(arg1=37.8800011, arg2=...) at main.c:xxx
> #1 0x00007ffff746e4e0 in ffi_call_unix64 () at x86/unix64.S:xxx
> #2 0x00007ffff746dac8 in ffi_call (cif=0x7ffff7d44e90, fn=0x7ffff7f9e060,
> rvalue=0x16818, avalue=0x7ffff7d44f30) at x86/ffi64.c:xxx
>
> Thread 2 "main" hit Breakpoint 2, testNestedFloatStruct(arg1=37.8800011,
> arg2=...) at main.c
> float floatSum = arg1 + arg2.elem1 + arg2.elem2.elem1 +
> arg2.elem2.elem2;
> (gdb) p arg2
> $4 = {
> elem1 = 31.2199993,
> elem2 = {
> elem1 = 33.4399986,
> elem2 = 4.20389539e-45 <------------------ messed up
> }
> }
>
> (gdb) x/10x &arg2
> 0x7ffff7d44458: 0x41f9c28f 0x4205c28f 0x00000003 0x00007fff
> 0x7ffff7d44468: 0xf70cf1e6 0x4217851f 0xf7d44510 0x00007fff
> 0x7ffff7d44478: 0xf7d44660 0x00007fff
>
>
> -------------------------------------------
>
> It looks like there is something wrong in dealing with the nested stuct on
> Linux/64bit in x86/libffi as the test above works good on Windows/64bit.
>
>
> Thanks and Best Regards
> Cheng Jin
>
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* RE: Incorrect data detected in the nested float struct with x86/libffi on Linux/64bit
2021-06-09 16:50 ` Anthony Green
@ 2021-06-09 17:53 ` Cheng Jin
2021-06-15 18:02 ` Jakub Jelinek
1 sibling, 0 replies; 10+ messages in thread
From: Cheng Jin @ 2021-06-09 17:53 UTC (permalink / raw)
To: Anthony Green; +Cc: libffi-discuss
[-- Attachment #1: Type: text/plain, Size: 5628 bytes --]
Hi Anthony,
Many thanks for the quick response. The PR has been created at
https://github.com/libffi/libffi/pull/640 as requested.
Thanks and Best Regards
Cheng Jin
From: Anthony Green <green@moxielogic.com>
To: Cheng Jin <jincheng@ca.ibm.com>
Cc: libffi-discuss <libffi-discuss@sourceware.org>
Date: 2021-06-09 12:50 PM
Subject: [EXTERNAL] Re: Incorrect data detected in the nested float
struct with x86/libffi on Linux/64bit
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. Thanks, AG On Wed, Jun 9, 2021 at 12:41 PM Cheng Jin via
Libffi-discuss < ZjQcmQRYFpfptBannerStart
This Message Is From an External Sender
This message came from outside your organization.
ZjQcmQRYFpfptBannerEnd
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.
Thanks,
AG
On Wed, Jun 9, 2021 at 12:41 PM Cheng Jin via Libffi-discuss <
libffi-discuss@sourceware.org> 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:
typedef struct stru_Nested_F stru_Nested_F;
struct stru_FF {
float elem1;
float elem2;
};
struct stru_Nested_F {
float elem1;
stru_FF elem2;
};
static float testNestedFloatStruct(float arg1, stru_Nested_F arg2)
{
float floatSum = arg1 + arg2.elem1 + arg2.elem2.elem1 +
arg2.elem2.elem2;
return floatSum;
}
int main() {
float returnValue = 0;
ffi_cif cif_temp;
UDATA structElemNum = 2;
UDATA nestedStructElemNum = 2;
UDATA argNum = 2;
ffi_type **cls_struct_fields1 = (ffi_type
**)malloc(sizeof(ffi_type
*) * (structElemNum + 1));
ffi_type **cls_struct_fields2 = (ffi_type
**)malloc(sizeof(ffi_type
*) * (nestedStructElemNum + 1));
ffi_type **dbl_arg_types = (ffi_type **)malloc(sizeof(ffi_type
*) *
(argNum + 1));
void **args_db = (void **)malloc(sizeof(void *) * (argNum +
1));
ffi_type cls_struct_type1, cls_struct_type2;
ffi_type *retType = &ffi_type_float;
float arg1;
float *arg2 = (float *)malloc(sizeof(stru_Nested_F));
cls_struct_fields2[0] = &ffi_type_float;
cls_struct_fields2[1] = &ffi_type_float;
cls_struct_fields2[2] = NULL;
cls_struct_type2.size = 0;
cls_struct_type2.alignment = 0;
cls_struct_type2.type = FFI_TYPE_STRUCT;
cls_struct_type2.elements = cls_struct_fields2;
cls_struct_fields1[0] = &ffi_type_float;
cls_struct_fields1[1] = &cls_struct_type2;
cls_struct_fields1[2] = NULL;
cls_struct_type1.size = 0;
cls_struct_type1.alignment = 0;
cls_struct_type1.type = FFI_TYPE_STRUCT;
cls_struct_type1.elements = cls_struct_fields1;
dbl_arg_types[0] = &ffi_type_float;
dbl_arg_types[1] = &cls_struct_type1;
dbl_arg_types[2] = NULL;
ffi_prep_cif(&cif_temp, FFI_DEFAULT_ABI, 2, retType,
dbl_arg_types);
arg1 = 37.88;
arg2[0] = 31.22;
arg2[1] = 33.44;
arg2[2] = 35.66;
args_db[0] = &arg1;
args_db[1] = arg2;
args_db[2] = NULL;
ffi_call(&cif_temp, FFI_FN(testNestedFloatStruct), &returnValue,
args_db);
free(cls_struct_fields1);
free(cls_struct_fields2);
free(dbl_arg_types);
free(args_db);
return 0;
}
with the debugging output as follows:
(gdb) p arg2[0]
$1 = 31.2199993
(gdb) p arg2[1]
$2 = 33.4399986
(gdb) p arg2[2]
$3 = 35.6599998
(gdb) x/10x arg2
0x7ffff025b540: 0x41f9c28f 0x4205c28f 0x420ea3d7
0xdddddddd
0x7ffff025b550: 0xb7654321 0x475d4352 0x0000000c
0x00000000
0x7ffff025b560: 0xf749c970 0x00007fff
(gdb) bt
#0 testNestedFloatStruct(arg1=37.8800011, arg2=...) at main.c:xxx
#1 0x00007ffff746e4e0 in ffi_call_unix64 () at x86/unix64.S:xxx
#2 0x00007ffff746dac8 in ffi_call (cif=0x7ffff7d44e90,
fn=0x7ffff7f9e060,
rvalue=0x16818, avalue=0x7ffff7d44f30) at x86/ffi64.c:xxx
Thread 2 "main" hit Breakpoint 2, testNestedFloatStruct(arg1=37.8800011,
arg2=...) at main.c
float floatSum = arg1 + arg2.elem1 + arg2.elem2.elem1 +
arg2.elem2.elem2;
(gdb) p arg2
$4 = {
elem1 = 31.2199993,
elem2 = {
elem1 = 33.4399986,
elem2 = 4.20389539e-45 <------------------ messed up
}
}
(gdb) x/10x &arg2
0x7ffff7d44458: 0x41f9c28f 0x4205c28f 0x00000003
0x00007fff
0x7ffff7d44468: 0xf70cf1e6 0x4217851f 0xf7d44510
0x00007fff
0x7ffff7d44478: 0xf7d44660 0x00007fff
-------------------------------------------
It looks like there is something wrong in dealing with the nested stuct
on
Linux/64bit in x86/libffi as the test above works good on Windows/64bit.
Thanks and Best Regards
Cheng Jin
[-- Attachment #2: graycol.gif --]
[-- Type: image/gif, Size: 105 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Incorrect data detected in the nested float struct with x86/libffi on Linux/64bit
2021-06-09 16:41 Incorrect data detected in the nested float struct with x86/libffi on Linux/64bit Cheng Jin
2021-06-09 16:50 ` 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)
2 siblings, 1 reply; 10+ messages in thread
From: Kaz Kylheku (libffi) @ 2021-06-09 23:48 UTC (permalink / raw)
To: Cheng Jin; +Cc: libffi-discuss
On 2021-06-09 09:41, Cheng Jin via Libffi-discuss wrote:
> Hi,
Hi Cheng Jin,
A small matter on a tangent.
>
> cls_struct_fields1[0] = &ffi_type_float;
> cls_struct_fields1[1] = &cls_struct_type2;
> cls_struct_fields1[2] = NULL;
Indeed, the array describing the element types of a structure must be
null terminated, so this is required.
> cls_struct_type1.size = 0;
> cls_struct_type1.alignment = 0;
> cls_struct_type1.type = FFI_TYPE_STRUCT;
> cls_struct_type1.elements = cls_struct_fields1;
Note that here, the size of the object is not indicated. That's why
the extra null pointer is required to infer the size.
>
> dbl_arg_types[0] = &ffi_type_float;
> dbl_arg_types[1] = &cls_struct_type1;
> dbl_arg_types[2] = NULL;
But, for the argument array of a ffi_cif, no null termination is
required.
> ffi_prep_cif(&cif_temp, FFI_DEFAULT_ABI, 2, retType, dbl_arg_types);
No requirement for a null terminator is documented or appears in
examples. The 2 argument indicates the number of elements.
There is no harm in it; just pointing it out.
When I looked at your code, I went scrambling through documentation
to see if I was missing a required null terminator. :)
Cheers ...
^ permalink raw reply [flat|nested] 10+ messages in thread
* RE: Incorrect data detected in the nested float struct with x86/libffi on Linux/64bit
2021-06-09 23:48 ` Kaz Kylheku (libffi)
@ 2021-06-10 0:21 ` Cheng Jin
0 siblings, 0 replies; 10+ messages in thread
From: Cheng Jin @ 2021-06-10 0:21 UTC (permalink / raw)
To: Kaz Kylheku (libffi); +Cc: libffi-discuss
[-- Attachment #1: Type: text/plain, Size: 2007 bytes --]
Hi Kaz,
Many thanks for your comments on the test code.
Actually it is not the test case used in our project but just to verify
whether it works good as expected.
The test code (already merged to the libffi tests at
https://github.com/libffi/libffi/pull/640 as requested by them) was
identified as a bug specific to x86_64 which will be investigated to see
what happens.
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 07:48 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,
Hi Cheng Jin,
A small matter on a tangent.
>
> cls_struct_fields1[0] = &ffi_type_float;
> cls_struct_fields1[1] = &cls_struct_type2;
> cls_struct_fields1[2] = NULL;
Indeed, the array describing the element types of a structure must be
null terminated, so this is required.
> cls_struct_type1.size = 0;
> cls_struct_type1.alignment = 0;
> cls_struct_type1.type = FFI_TYPE_STRUCT;
> cls_struct_type1.elements = cls_struct_fields1;
Note that here, the size of the object is not indicated. That's why
the extra null pointer is required to infer the size.
>
> dbl_arg_types[0] = &ffi_type_float;
> dbl_arg_types[1] = &cls_struct_type1;
> dbl_arg_types[2] = NULL;
But, for the argument array of a ffi_cif, no null termination is
required.
> ffi_prep_cif(&cif_temp, FFI_DEFAULT_ABI, 2, retType,
dbl_arg_types);
No requirement for a null terminator is documented or appears in
examples. The 2 argument indicates the number of elements.
There is no harm in it; just pointing it out.
When I looked at your code, I went scrambling through documentation
to see if I was missing a required null terminator. :)
Cheers ...
[-- Attachment #2: graycol.gif --]
[-- Type: image/gif, Size: 105 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Incorrect data detected in the nested float struct with x86/libffi on Linux/64bit
2021-06-09 16:41 Incorrect data detected in the nested float struct with x86/libffi on Linux/64bit Cheng Jin
2021-06-09 16:50 ` Anthony Green
2021-06-09 23:48 ` Kaz Kylheku (libffi)
@ 2021-06-10 2:05 ` Kaz Kylheku (libffi)
2021-06-10 2:39 ` Cheng Jin
2 siblings, 1 reply; 10+ messages in thread
From: Kaz Kylheku (libffi) @ 2021-06-10 2:05 UTC (permalink / raw)
To: Cheng Jin; +Cc: libffi-discuss
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.
^ permalink raw reply [flat|nested] 10+ messages in thread
* RE: Incorrect data detected in the nested float struct with x86/libffi on Linux/64bit
2021-06-10 2:05 ` Kaz Kylheku (libffi)
@ 2021-06-10 2:39 ` Cheng Jin
0 siblings, 0 replies; 10+ messages in thread
From: Cheng Jin @ 2021-06-10 2:39 UTC (permalink / raw)
To: Kaz Kylheku (libffi); +Cc: libffi-discuss
[-- 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 --]
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Incorrect data detected in the nested float struct with x86/libffi on Linux/64bit
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
1 sibling, 1 reply; 10+ messages in thread
From: Jakub Jelinek @ 2021-06-15 18:02 UTC (permalink / raw)
To: Anthony Green; +Cc: Cheng Jin, libffi-discuss, DJ Delorie
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 <jakub@redhat.com>
* 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
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Incorrect data detected in the nested float struct with x86/libffi on Linux/64bit
2021-06-15 18:02 ` Jakub Jelinek
@ 2021-06-15 19:02 ` Jakub Jelinek
2021-06-15 19:29 ` Anthony Green
0 siblings, 1 reply; 10+ messages in thread
From: Jakub Jelinek @ 2021-06-15 19:02 UTC (permalink / raw)
To: Anthony Green, libffi-discuss
On Tue, Jun 15, 2021 at 08:02:56PM +0200, Jakub Jelinek via Libffi-discuss wrote:
> 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.
And here is one with a testcase (modified nested_struct2.c for it).
I'm unsure about the current relationship between the github and gcc
copy of libffi, shall it go to both, or just one of them and be
cherry-picked from there?
Tested on x86_64-linux.
2021-06-15 Jakub Jelinek <jakub@redhat.com>
* 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.
* testsuite/libffi.call/nested_struct12.c: New test.
--- 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]);
}
--- libffi/testsuite/libffi.call/nested_struct12.c.jj 2021-06-15 20:31:43.327144303 +0200
+++ libffi/testsuite/libffi.call/nested_struct12.c 2021-06-15 20:47:13.129489263 +0200
@@ -0,0 +1,107 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure passing.
+ Limitations: none.
+ PR: none.
+ Originator: <jincheng@ca.ibm.com> and <jakub@redhat.com> 20210609 */
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+typedef struct A {
+ float a, b;
+} A;
+
+typedef struct B {
+ float x;
+ struct A y;
+} B;
+
+B B_fn(float b0, struct B b1)
+{
+ struct B result;
+
+ result.x = b0 + b1.x;
+ result.y.a = b0 + b1.y.a;
+ result.y.b = b0 + b1.y.b;
+
+ printf("%g %g %g %g: %g %g %g\n", b0, b1.x, b1.y.a, b1.y.b,
+ result.x, result.y.a, result.y.b);
+
+ return result;
+}
+
+static void
+B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+ float b0;
+ struct B b1;
+
+ b0 = *(float*)(args[0]);
+ b1 = *(struct B*)(args[1]);
+
+ *(B*)resp = B_fn(b0, b1);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[3];
+ ffi_type* cls_struct_fields[3];
+ ffi_type* cls_struct_fields1[3];
+ ffi_type cls_struct_type, cls_struct_type1;
+ ffi_type* dbl_arg_types[3];
+
+ float e_dbl = 12.125f;
+ struct B f_dbl = { 24.75f, { 31.625f, 32.25f } };
+
+ struct B res_dbl;
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ cls_struct_type1.size = 0;
+ cls_struct_type1.alignment = 0;
+ cls_struct_type1.type = FFI_TYPE_STRUCT;
+ cls_struct_type1.elements = cls_struct_fields1;
+
+ cls_struct_fields[0] = &ffi_type_float;
+ cls_struct_fields[1] = &ffi_type_float;
+ cls_struct_fields[2] = NULL;
+
+ cls_struct_fields1[0] = &ffi_type_float;
+ cls_struct_fields1[1] = &cls_struct_type;
+ cls_struct_fields1[2] = NULL;
+
+
+ dbl_arg_types[0] = &ffi_type_float;
+ dbl_arg_types[1] = &cls_struct_type1;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type1,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &e_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl);
+ /* { dg-output "12.125 24.75 31.625 32.25: 36.875 43.75 44.375" } */
+ CHECK( res_dbl.x == (e_dbl + f_dbl.x));
+ CHECK( res_dbl.y.a == (e_dbl + f_dbl.y.a));
+ CHECK( res_dbl.y.b == (e_dbl + f_dbl.y.b));
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((B(*)(float, B))(code))(e_dbl, f_dbl);
+ /* { dg-output "\n12.125 24.75 31.625 32.25: 36.875 43.75 44.375" } */
+ CHECK( res_dbl.x == (e_dbl + f_dbl.x));
+ CHECK( res_dbl.y.a == (e_dbl + f_dbl.y.a));
+ CHECK( res_dbl.y.b == (e_dbl + f_dbl.y.b));
+
+ exit(0);
+}
Jakub
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Incorrect data detected in the nested float struct with x86/libffi on Linux/64bit
2021-06-15 19:02 ` Jakub Jelinek
@ 2021-06-15 19:29 ` Anthony Green
0 siblings, 0 replies; 10+ messages in thread
From: Anthony Green @ 2021-06-15 19:29 UTC (permalink / raw)
To: Jakub Jelinek; +Cc: libffi-discuss
Thank you, Jakub! This has been committed.
AG
On Tue, Jun 15, 2021 at 3:02 PM Jakub Jelinek <jakub@redhat.com> wrote:
> On Tue, Jun 15, 2021 at 08:02:56PM +0200, Jakub Jelinek via Libffi-discuss
> wrote:
> > 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.
>
> And here is one with a testcase (modified nested_struct2.c for it).
>
> I'm unsure about the current relationship between the github and gcc
> copy of libffi, shall it go to both, or just one of them and be
> cherry-picked from there?
>
> Tested on x86_64-linux.
>
> 2021-06-15 Jakub Jelinek <jakub@redhat.com>
>
> * 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.
> * testsuite/libffi.call/nested_struct12.c: New test.
>
> --- 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]);
> }
> --- libffi/testsuite/libffi.call/nested_struct12.c.jj 2021-06-15
> 20:31:43.327144303 +0200
> +++ libffi/testsuite/libffi.call/nested_struct12.c 2021-06-15
> 20:47:13.129489263 +0200
> @@ -0,0 +1,107 @@
> +/* Area: ffi_call, closure_call
> + Purpose: Check structure passing.
> + Limitations: none.
> + PR: none.
> + Originator: <jincheng@ca.ibm.com> and <jakub@redhat.com> 20210609
> */
> +
> +/* { dg-do run } */
> +#include "ffitest.h"
> +
> +typedef struct A {
> + float a, b;
> +} A;
> +
> +typedef struct B {
> + float x;
> + struct A y;
> +} B;
> +
> +B B_fn(float b0, struct B b1)
> +{
> + struct B result;
> +
> + result.x = b0 + b1.x;
> + result.y.a = b0 + b1.y.a;
> + result.y.b = b0 + b1.y.b;
> +
> + printf("%g %g %g %g: %g %g %g\n", b0, b1.x, b1.y.a, b1.y.b,
> + result.x, result.y.a, result.y.b);
> +
> + return result;
> +}
> +
> +static void
> +B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
> + void* userdata __UNUSED__)
> +{
> + float b0;
> + struct B b1;
> +
> + b0 = *(float*)(args[0]);
> + b1 = *(struct B*)(args[1]);
> +
> + *(B*)resp = B_fn(b0, b1);
> +}
> +
> +int main (void)
> +{
> + ffi_cif cif;
> + void *code;
> + ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
> + void* args_dbl[3];
> + ffi_type* cls_struct_fields[3];
> + ffi_type* cls_struct_fields1[3];
> + ffi_type cls_struct_type, cls_struct_type1;
> + ffi_type* dbl_arg_types[3];
> +
> + float e_dbl = 12.125f;
> + struct B f_dbl = { 24.75f, { 31.625f, 32.25f } };
> +
> + struct B res_dbl;
> +
> + cls_struct_type.size = 0;
> + cls_struct_type.alignment = 0;
> + cls_struct_type.type = FFI_TYPE_STRUCT;
> + cls_struct_type.elements = cls_struct_fields;
> +
> + cls_struct_type1.size = 0;
> + cls_struct_type1.alignment = 0;
> + cls_struct_type1.type = FFI_TYPE_STRUCT;
> + cls_struct_type1.elements = cls_struct_fields1;
> +
> + cls_struct_fields[0] = &ffi_type_float;
> + cls_struct_fields[1] = &ffi_type_float;
> + cls_struct_fields[2] = NULL;
> +
> + cls_struct_fields1[0] = &ffi_type_float;
> + cls_struct_fields1[1] = &cls_struct_type;
> + cls_struct_fields1[2] = NULL;
> +
> +
> + dbl_arg_types[0] = &ffi_type_float;
> + dbl_arg_types[1] = &cls_struct_type1;
> + dbl_arg_types[2] = NULL;
> +
> + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type1,
> + dbl_arg_types) == FFI_OK);
> +
> + args_dbl[0] = &e_dbl;
> + args_dbl[1] = &f_dbl;
> + args_dbl[2] = NULL;
> +
> + ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl);
> + /* { dg-output "12.125 24.75 31.625 32.25: 36.875 43.75 44.375" } */
> + CHECK( res_dbl.x == (e_dbl + f_dbl.x));
> + CHECK( res_dbl.y.a == (e_dbl + f_dbl.y.a));
> + CHECK( res_dbl.y.b == (e_dbl + f_dbl.y.b));
> +
> + CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
> +
> + res_dbl = ((B(*)(float, B))(code))(e_dbl, f_dbl);
> + /* { dg-output "\n12.125 24.75 31.625 32.25: 36.875 43.75 44.375" } */
> + CHECK( res_dbl.x == (e_dbl + f_dbl.x));
> + CHECK( res_dbl.y.a == (e_dbl + f_dbl.y.a));
> + CHECK( res_dbl.y.b == (e_dbl + f_dbl.y.b));
> +
> + exit(0);
> +}
>
>
> Jakub
>
>
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2021-06-15 19:29 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-09 16:41 Incorrect data detected in the nested float struct with x86/libffi on Linux/64bit 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 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).