From: Aaron R <aaronr.mb@gmail.com>
To: libffi-discuss@sourceware.org
Subject: PPC bug when handling double
Date: Sat, 01 Aug 2015 15:59:00 -0000 [thread overview]
Message-ID: <CAAJF+L=4KZdzCDwmLZhhsQLpr4+_CFE+MFDtpgNPY+jBooZvgA@mail.gmail.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 1682 bytes --]
Hi,
I am not very familiar with libffi but I believe I may have stumbled upon a bug.
If you build the attached test code, you will get two test programs -
namely, ex1 and ex2. The only difference between the two is
'-D__USE_F6__' , which passes the last parameter of test_func1() as a
float instead of a double. I have tried these test programs on both
X86 and PPC (32-bit in both cases) using libffi 3.2.1. I did not use
any special configure flags when I built libffi 3.2.1 for both
platforms.
This is what I get on X86:
$ ./ex1
args_idx = 12
tst_func1 : 0xa 0xb 11.100000 12.1 13.100000 14.1 15.100000 16.1
17.100000 18.1 19.100000 20.100000
rc = 1 - success? Y
$ ./ex2
args_idx = 12
tst_func1 : 0xa 0xb 11.100000 12.1 13.100000 14.1 15.100000 16.1
17.100000 18.1 19.100000 20.1
rc = 1 - success? Y
That looks fine. The last parameter is always 20.1.
If I run the same code on PPC I get:
$ uname -a
Linux tstsrv 3.0.101-0.47.52-ppc64 #1 SMP Thu Mar 26 10:55:49 UTC 2015
(0e3c7c8) ppc64 ppc64 ppc64 GNU/Linux
$ file ./ppc/libffi_3.2.1/lib/libffi.so.6.0.4
./ppc/libffi_3.2.1/lib/libffi.so.6.0.4: ELF 32-bit MSB shared object,
PowerPC or cisco 4500, version 1 (SYSV), dynamically linked, not
stripped
$ gcc -dumpversion
4.3
$ ./ex1
args_idx = 12
tst_func1 : 0xa 0xb 11.100000 12.1 13.100000 14.1 15.100000 16.1
17.100000 18.1 19.100000 20.100000
rc = 1 - success? Y
$ ./ex2
args_idx = 12
tst_func1 : 0xa 0xb 11.100000 12.1 13.100000 14.1 15.100000 16.1
17.100000 18.1 19.100000 -2.35344e-185
rc = 0 - success? N
You can see above that the last parameter printed by tst_func1() is
incorrect in the case of ex2 (i.e., when passed as a double).
Any idea?
Thanks in advance
[-- Attachment #2: ex.c --]
[-- Type: text/x-csrc, Size: 3794 bytes --]
#include <stdint.h>
#include <stdio.h>
#include <ffi.h>
#include "trg.h"
#define NUM_TST_ARGS 12
#define FFI_FN(f) ((void (*)(void))f)
static int test1(void) {
uint32_t sValues[2 * NUM_TST_ARGS];
size_t sValues_idx = 0;
ffi_cif cif;
ffi_type *args[NUM_TST_ARGS];
size_t args_idx = 0;
void *values[NUM_TST_ARGS];
int rc = -1;
/* Initialize the argument info vectors */
args[args_idx] = &ffi_type_pointer;
sValues[sValues_idx] = (uint32_t) 0xa;
values[args_idx] = &(sValues[sValues_idx]);
++args_idx;
++sValues_idx;
args[args_idx] = &ffi_type_pointer;
sValues[sValues_idx] = (uint32_t) 0xb;
values[args_idx] = &(sValues[sValues_idx]);
++args_idx;
++sValues_idx;
args[args_idx] = &ffi_type_float;
{
const float tf = 11.1;
const uint32_t * const tp = (uint32_t *) &tf;
sValues[sValues_idx] = *tp;
}
values[args_idx] = &(sValues[sValues_idx]);
++args_idx;
++sValues_idx;
args[args_idx] = &ffi_type_double;
{
const double tf = 12.1;
const uint32_t * const tp = (uint32_t *) &tf;
sValues[sValues_idx] = *tp;
++sValues_idx;
sValues[sValues_idx] = *(tp + 1);
}
values[args_idx] = &(sValues[sValues_idx - 1]);
++args_idx;
++sValues_idx;
args[args_idx] = &ffi_type_float;
{
const float tf = 13.1;
const uint32_t * const tp = (uint32_t *) &tf;
sValues[sValues_idx] = *tp;
}
values[args_idx] = &(sValues[sValues_idx]);
++args_idx;
++sValues_idx;
args[args_idx] = &ffi_type_double;
{
const double tf = 14.1;
const uint32_t * const tp = (uint32_t *) &tf;
sValues[sValues_idx] = *tp;
++sValues_idx;
sValues[sValues_idx] = *(tp + 1);
}
values[args_idx] = &(sValues[sValues_idx - 1]);
++args_idx;
++sValues_idx;
args[args_idx] = &ffi_type_float;
{
const float tf = 15.1;
const uint32_t * const tp = (uint32_t *) &tf;
sValues[sValues_idx] = *tp;
}
values[args_idx] = &(sValues[sValues_idx]);
++args_idx;
++sValues_idx;
args[args_idx] = &ffi_type_double;
{
const double tf = 16.1;
const uint32_t * const tp = (uint32_t *) &tf;
sValues[sValues_idx] = *tp;
++sValues_idx;
sValues[sValues_idx] = *(tp + 1);
}
values[args_idx] = &(sValues[sValues_idx - 1]);
++args_idx;
++sValues_idx;
args[args_idx] = &ffi_type_float;
{
const float tf = 17.1;
const uint32_t * const tp = (uint32_t *) &tf;
sValues[sValues_idx] = *tp;
}
values[args_idx] = &(sValues[sValues_idx]);
++args_idx;
++sValues_idx;
args[args_idx] = &ffi_type_double;
{
const double tf = 18.1;
const uint32_t * const tp = (uint32_t *) &tf;
sValues[sValues_idx] = *tp;
++sValues_idx;
sValues[sValues_idx] = *(tp + 1);
}
values[args_idx] = &(sValues[sValues_idx - 1]);
++args_idx;
++sValues_idx;
args[args_idx] = &ffi_type_float;
{
const float tf = 19.1;
const uint32_t * const tp = (uint32_t *) &tf;
sValues[sValues_idx] = *tp;
}
values[args_idx] = &(sValues[sValues_idx]);
++args_idx;
++sValues_idx;
#ifdef __USE_F6__
args[args_idx] = &ffi_type_float;
{
const float tf = 20.1;
const uint32_t * const tp = (uint32_t *) &tf;
sValues[sValues_idx] = *tp;
}
values[args_idx] = &(sValues[sValues_idx]);
++args_idx;
++sValues_idx;
#else /* __USE_F6__ */
args[args_idx] = &ffi_type_double;
{
const double tf = 20.1;
const uint32_t * const tp = (uint32_t *) &tf;
sValues[sValues_idx] = *tp;
++sValues_idx;
sValues[sValues_idx] = *(tp + 1);
}
values[args_idx] = &(sValues[sValues_idx - 1]);
++args_idx;
++sValues_idx;
#endif /* __USE_F6__ */
printf("args_idx = %d\n", args_idx);
/* Initialize the cif and issue ffi call */
if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, NUM_TST_ARGS, &ffi_type_uint, args) == FFI_OK) {
ffi_call(&cif, FFI_FN(tst_func1), &rc, values);
printf("rc = %d - success? %c\n", rc, (1 == rc) ? 'Y' : 'N');
}
return rc;
}
int main() {
return test1();
}
[-- Attachment #3: Makefile --]
[-- Type: application/octet-stream, Size: 710 bytes --]
all: x86
x86: x86_ex1 x86_ex2
ppc: ppc_ex1 ppc_ex2
trg1:
gcc -D__USE_F6__ -g -m32 -c trg.c -o trg1.o
x86_ex1: trg1
gcc -D__USE_F6__ -g -m32 -I./x86/libffi_3.2.1/lib/libffi-3.2.1/include/ -L./x86/libffi_3.2.1/lib/ ex.c -o ex1 trg1.o -lffi
ppc_ex1: trg1
gcc -D__USE_F6__ -g -m32 -I./ppc/libffi_3.2.1/lib/libffi-3.2.1/include/ -L./ppc/libffi_3.2.1/lib/ ex.c -o ex1 trg1.o -lffi
trg2:
gcc -g -m32 -c trg.c -o trg2.o
x86_ex2: trg2
gcc -g -m32 -I./x86/libffi_3.2.1/lib/libffi-3.2.1/include/ -L./x86/libffi_3.2.1/lib/ ex.c -o ex2 trg2.o -lffi
ppc_ex2: trg2
gcc -g -m32 -I./ppc/libffi_3.2.1/lib/libffi-3.2.1/include/ -L./ppc/libffi_3.2.1/lib/ ex.c -o ex2 trg2.o -lffi
clean:
rm -f *.o ex1 ex2
[-- Attachment #4: trg.c --]
[-- Type: text/x-csrc, Size: 1246 bytes --]
#include <stdio.h>
int tst_func1(const char * p1, const char * p2, float f1, double d1, float f2, double d2,
#ifdef __USE_F6__
float f3, double d3, float f4, double d4, float f5, float f6)
#else /* __USE_F6__ */
float f3, double d3, float f4, double d4, float f5, double d5)
#endif /* __USE_F6__ */
{
const int success =
((const char *) 0xa == p1) &&
((const char *) 0xb == p2) &&
((float) 11.1 == f1) &&
((double) 12.1 == d1) &&
((float) 13.1 == f2) &&
((double) 14.1 == d2) &&
((float) 15.1 == f3) &&
((double) 16.1 == d3) &&
((float) 17.1 == f4) &&
((double) 18.1 == d4) &&
((float) 19.1 == f5) &&
#ifdef __USE_F6__
((float) 20.1 == f6);
#else /* __USE_F6__ */
((double) 20.1 == d5);
#endif /* __USE_F6__ */
#ifdef __USE_F6__
printf("%s : %p %p %f %g %f %g %f %g %f %g %f %f\n",
#else /* __USE_F6__ */
printf("%s : %p %p %f %g %f %g %f %g %f %g %f %g\n",
#endif /* __USE_F6__ */
__func__,
p1,
p2,
f1,
d1,
f2,
d2,
f3,
d3,
f4,
d4,
f5,
#ifdef __USE_F6__
f6);
#else /* __USE_F6__ */
d5);
#endif /* __USE_F6__ */
return success;
}
[-- Attachment #5: trg.h --]
[-- Type: text/x-chdr, Size: 347 bytes --]
#ifndef __TRG_H__
#define __TRG_H__
int tst_func1(const char * p1, const char * p2, float f1, double d1, float f2, double d2,
#ifdef __USE_F6__
float f3, double d3, float f4, double d4, float f5, float f6);
#else /* __USE_F6__ */
float f3, double d3, float f4, double d4, float f5, double d5);
#endif /* __USE_F6__ */
#endif /* __TRG_H__ */
next reply other threads:[~2015-08-01 15:59 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-08-01 15:59 Aaron R [this message]
2015-08-03 5:31 ` Alan Modra
2015-08-03 15:10 ` Alan Modra
2015-08-04 11:46 ` Aaron R
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='CAAJF+L=4KZdzCDwmLZhhsQLpr4+_CFE+MFDtpgNPY+jBooZvgA@mail.gmail.com' \
--to=aaronr.mb@gmail.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).