public inbox for libffi-discuss@sourceware.org
 help / color / mirror / Atom feed
* PPC bug when handling double
@ 2015-08-01 15:59 Aaron R
  2015-08-03  5:31 ` Alan Modra
  0 siblings, 1 reply; 4+ messages in thread
From: Aaron R @ 2015-08-01 15:59 UTC (permalink / raw)
  To: libffi-discuss

[-- 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__ */


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2015-08-04 11:46 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-08-01 15:59 PPC bug when handling double Aaron R
2015-08-03  5:31 ` Alan Modra
2015-08-03 15:10   ` Alan Modra
2015-08-04 11:46     ` Aaron R

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