This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug libffi/26744] New: ffi_call can't pass floating-point values to a function which has variable argument list.
- From: "naoki at koguro dot net" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 18 Mar 2006 13:50:16 -0000
- Subject: [Bug libffi/26744] New: ffi_call can't pass floating-point values to a function which has variable argument list.
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
In MacOSX 10.4.5, ffi_call can't pass floating-point values to a function which
has variable argument list.
=== Reproduce steps:
(1) compile the test program
% cat vaarg.c
#include <stdio.h>
#include <ffi.h>
int main()
{
ffi_cif cif;
ffi_type *args[2];
void *values[1];
double v = 0.5;
int rc;
char *fmt = "%lf\n";
args[0] = &ffi_type_pointer;
values[0] = &fmt;
args[1] = &ffi_type_double;
values[1] = &v;
if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ffi_type_sint, args) ==
FFI_OK) {
ffi_call(&cif, (void*)printf, &rc, values);
}
return 0;
}
% gcc -v -save-temps -o vaarg vaarg.c -I../src/libffi/include/
../src/libffi/.libs/libffi.a
Using built-in specs.
Target: powerpc-apple-darwin8
Configured with: /private/var/tmp/gcc/gcc-5247.obj~4/src/configure
--disable-checking -enable-werror --prefix=/usr --mandir=/share/man
--enable-languages=c,objc,c++,obj-c++
--program-transform-name=/^[cg][^.-]*$/s/$/-4.0/
--with-gxx-include-dir=/include/c++/4.0.0 --build=powerpc-apple-darwin8
--host=powerpc-apple-darwin8 --target=powerpc-apple-darwin8
Thread model: posix
gcc version 4.0.1 (Apple Computer, Inc. build 5247)
/usr/libexec/gcc/powerpc-apple-darwin8/4.0.1/cc1 -E -quiet -v
-I../src/libffi/include/ -D__DYNAMIC__ vaarg.c -fPIC -fpch-preprocess -o
vaarg.i
ignoring nonexistent directory
"/usr/lib/gcc/powerpc-apple-darwin8/4.0.1/../../../../powerpc-apple-darwin8/include"
#include "..." search starts here:
#include <...> search starts here:
../src/libffi/include/
/usr/local/include
/usr/lib/gcc/powerpc-apple-darwin8/4.0.1/include
/usr/include
/System/Library/Frameworks
/Library/Frameworks
End of search list.
/usr/libexec/gcc/powerpc-apple-darwin8/4.0.1/cc1 -fpreprocessed vaarg.i -fPIC
-quiet -dumpbase vaarg.c -auxbase vaarg -version -o vaarg.s
GNU C version 4.0.1 (Apple Computer, Inc. build 5247) (powerpc-apple-darwin8)
compiled by GNU C version 4.0.1 (Apple Computer, Inc. build 5247).
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 293c7bb043389dbe08b10e2d17bba0c4
as -arch ppc -o vaarg.o vaarg.s
/usr/libexec/gcc/powerpc-apple-darwin8/4.0.1/collect2 -dynamic -arch ppc
-weak_reference_mismatches non-weak -o vaarg -lcrt1.o
/usr/lib/gcc/powerpc-apple-darwin8/4.0.1/crt2.o
-L/usr/lib/gcc/powerpc-apple-darwin8/4.0.1
-L/usr/lib/gcc/powerpc-apple-darwin8/4.0.1
-L/usr/lib/gcc/powerpc-apple-darwin8/4.0.1/../../.. vaarg.o
../src/libffi/.libs/libffi.a -lgcc -lSystemStubs -lSystem
(2) run it
% ./vaarg
-0.000000
=== Expected Results:
% ./vaarg
0.500000
=== Patches
For a function which has variable argument list, floating-point values should
be put in the stack even if fparg_count < NUM_FPR_ARG_REGISTERS.
URL:
http://developer.apple.com/documentation/DeveloperTools/Conceptual/LowLevelABI/Articles/32bitPowerPC.html#//apple_ref/doc/uid/TP40002438-DontLinkElementID_524797a
So I make the patch and works well in my environment.
% diff -c ffi_darwin.c.orig ffi_darwin.c
*** ffi_darwin.c.orig Sat Mar 18 21:23:17 2006
--- ffi_darwin.c Sat Mar 18 22:45:24 2006
***************
*** 130,138 ****
the size of the floating-point parameter are skipped. */
case FFI_TYPE_FLOAT:
double_tmp = *(float *)*p_argv;
! if (fparg_count >= NUM_FPR_ARG_REGISTERS)
! *(double *)next_arg = double_tmp;
! else
*fpr_base++ = double_tmp;
next_arg++;
fparg_count++;
--- 130,137 ----
the size of the floating-point parameter are skipped. */
case FFI_TYPE_FLOAT:
double_tmp = *(float *)*p_argv;
! *(double *)next_arg = double_tmp;
! if (fparg_count < NUM_FPR_ARG_REGISTERS)
*fpr_base++ = double_tmp;
next_arg++;
fparg_count++;
***************
*** 141,149 ****
case FFI_TYPE_DOUBLE:
double_tmp = *(double *)*p_argv;
! if (fparg_count >= NUM_FPR_ARG_REGISTERS)
! *(double *)next_arg = double_tmp;
! else
*fpr_base++ = double_tmp;
next_arg += 2;
fparg_count++;
--- 140,147 ----
case FFI_TYPE_DOUBLE:
double_tmp = *(double *)*p_argv;
! *(double *)next_arg = double_tmp;
! if (fparg_count < NUM_FPR_ARG_REGISTERS)
*fpr_base++ = double_tmp;
next_arg += 2;
fparg_count++;
***************
*** 154,169 ****
case FFI_TYPE_LONGDOUBLE:
double_tmp = ((double *)*p_argv)[0];
! if (fparg_count >= NUM_FPR_ARG_REGISTERS)
! *(double *)next_arg = double_tmp;
! else
*fpr_base++ = double_tmp;
next_arg += 2;
fparg_count++;
double_tmp = ((double *)*p_argv)[1];
! if (fparg_count >= NUM_FPR_ARG_REGISTERS)
! *(double *)next_arg = double_tmp;
! else
*fpr_base++ = double_tmp;
next_arg += 2;
fparg_count++;
--- 152,165 ----
case FFI_TYPE_LONGDOUBLE:
double_tmp = ((double *)*p_argv)[0];
! *(double *)next_arg = double_tmp;
! if (fparg_count < NUM_FPR_ARG_REGISTERS)
*fpr_base++ = double_tmp;
next_arg += 2;
fparg_count++;
double_tmp = ((double *)*p_argv)[1];
! *(double *)next_arg = double_tmp;
! if (fparg_count < NUM_FPR_ARG_REGISTERS)
*fpr_base++ = double_tmp;
next_arg += 2;
fparg_count++;
--
Summary: ffi_call can't pass floating-point values to a function
which has variable argument list.
Product: gcc
Version: 4.1.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: libffi
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: naoki at koguro dot net
GCC build triplet: powerpc-apple-darwin8.5.0
GCC host triplet: powerpc-apple-darwin8.5.0
GCC target triplet: powerpc-apple-darwin8.5.0
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26744