public inbox for libffi-discuss@sourceware.org
 help / color / mirror / Atom feed
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__ */


             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).