Variadic functions and libffi

Andrew Haley aph@redhat.com
Thu Jan 6 10:36:00 GMT 2011


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.



More information about the Libffi-discuss mailing list