This is the mail archive of the libffi-discuss@sourceware.org mailing list for the libffi project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Variadic functions and libffi


On 01/05/2011 05:47 PM, David Gilbert wrote:
Hi,
   As part of the linaro toolchain effort for ARM, I've been asked to
look at Variadic function calls in libffi,
specifically for the ARM 'hard float' (aka PCS_VFP or FFI_VFP, armhf)
variant and wanted to see what
people thought before I dived in to it.

   The ARM hard float variant is a variant of the ABI in which floating
point values are passed in floating point
registers (as opposed to the standard ABI where FP values are still
passed in integer registers).  What makes
this ABI a little unusual is that for variadic functions it just falls
back to the standard all-integer-register ABI, and
thus, as an example, in the function:

double foo(double bar, char *str, ...)

the return value and the 'bar' would be passed in integer registers
even though they aren't actually variadic
parameters.

It doesn't seem like there is any way out of this except for an API
change to libffi to state that a variadic function is being
called - so as I see it the questions then are:

    1) Does libffi really support variadic functions and/or is there a
desire to?  There are big warnings in various places saying
  it doesn't - but then the testcases call variadic functions, and at
least Python and SWIG both show examples of using it (with FP values).
On the other hand there is an ancient gcc bug
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26744 to fix variadic on
PPC MacOS
marked as 'wishlist' because libffi doesn't support variadic.

2) What's a good/minimal API change.

3) Which FFI users actually use variadics and are hitting problems.

As for an API change, as far as ARM hard float is concerned we don't
actually care which parameters are
variadic, we just care that the function is declared variadic, so a
minimal change would be to define a FFI_DEFAULT_VARIADIC_ABI
that is the same as FFI_DEFAULT_ABI on everything except ARM hard
float, in which case it's set to FFI_SYSV, and when calling
ffi_prep_cif you would pass FFI_DEFAULT_VARIADIC_ABI rather than
FFI_DEFAULT_ABI for variadic calls.

That's simple for ARM but it seems unfair on any other architecture
that needs to fix things up.

I've had some discussion with Marcus Shawcroft (cc'd) and it looks
like the right solution is to declare a

'ffi_prep_cif_variadic'

that is just like ffi_prep_cif but also takes a 'nnamedargs' to say
the number of fixed args (and hence which arg is the 1st variadic).

I don't think this is such a great design, because you'd be doing the calculation about where to put the args at the time of the call. IMO it makes more sense to do as much precomputation as possible, by calling ffi_prep_cif_variadic with the actual number of fixed args and the actual number of varargs you intend to pass. In almost all usages of libffi you really will know the number of arguments to be passed when preparing the CIF. If you can precompute all this stuff you can even use a JIT to generate code for the call.

Andrew.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]