| Index: libffi/include/ffi.h.in |
| =================================================================== |
| --- libffi.orig/include/ffi.h.in |
| +++ libffi/include/ffi.h.in |
| @@ -207,6 +207,15 @@ typedef struct { |
| #endif |
| } ffi_cif; |
| |
| +/* Used internally, but overridden by some architectures */ |
| +ffi_status ffi_prep_cif_core(ffi_cif *cif, |
| + ffi_abi abi, |
| + unsigned int isvariadic, |
| + unsigned int nfixedargs, |
| + unsigned int ntotalargs, |
| + ffi_type *rtype, |
| + ffi_type **atypes); |
| + |
| /* ---- Definitions for the raw API -------------------------------------- */ |
| |
| #ifndef FFI_SIZEOF_ARG |
| @@ -384,6 +393,13 @@ ffi_status ffi_prep_cif(ffi_cif *cif, |
| ffi_type *rtype, |
| ffi_type **atypes); |
| |
| +ffi_status ffi_prep_cif_var(ffi_cif *cif, |
| + ffi_abi abi, |
| + unsigned int nfixedargs, |
| + unsigned int ntotalargs, |
| + ffi_type *rtype, |
| + ffi_type **atypes); |
| + |
| void ffi_call(ffi_cif *cif, |
| void (*fn)(void), |
| void *rvalue, |
| Index: libffi/include/ffi_common.h |
| =================================================================== |
| --- libffi.orig/include/ffi_common.h |
| +++ libffi/include/ffi_common.h |
| @@ -75,6 +75,8 @@ void ffi_type_test(ffi_type *a, char *fi |
| |
| /* Perform machine dependent cif processing */ |
| ffi_status ffi_prep_cif_machdep(ffi_cif *cif); |
| +ffi_status ffi_prep_cif_machdep_var(ffi_cif *cif, |
| + unsigned int nfixedargs, unsigned int ntotalargs); |
| |
| /* Extended cif, used in callback from assembly routine */ |
| typedef struct |
| Index: libffi/man/Makefile.am |
| =================================================================== |
| --- libffi.orig/man/Makefile.am |
| +++ libffi/man/Makefile.am |
| @@ -2,7 +2,7 @@ |
| |
| AUTOMAKE_OPTIONS=foreign |
| |
| -EXTRA_DIST = ffi.3 ffi_call.3 ffi_prep_cif.3 |
| +EXTRA_DIST = ffi.3 ffi_call.3 ffi_prep_cif.3 ffi_prep_cif_var.3 |
| |
| -man_MANS = ffi.3 ffi_call.3 ffi_prep_cif.3 |
| +man_MANS = ffi.3 ffi_call.3 ffi_prep_cif.3 ffi_prep_cif_var.3 |
| |
| Index: libffi/man/ffi.3 |
| =================================================================== |
| --- libffi.orig/man/ffi.3 |
| +++ libffi/man/ffi.3 |
| @@ -16,6 +16,15 @@ libffi, -lffi |
| .Fa "ffi_type **atypes" |
| .Fc |
| .Ft void |
| +.Fo ffi_prep_cif_var |
| +.Fa "ffi_cif *cif" |
| +.Fa "ffi_abi abi" |
| +.Fa "unsigned int nfixedargs" |
| +.Fa "unsigned int ntotalargs" |
| +.Fa "ffi_type *rtype" |
| +.Fa "ffi_type **atypes" |
| +.Fc |
| +.Ft void |
| .Fo ffi_call |
| .Fa "ffi_cif *cif" |
| .Fa "void (*fn)(void)" |
| @@ -28,4 +37,5 @@ generate a call to another function at r |
| the called function's interface at compile time. |
| .Sh SEE ALSO |
| .Xr ffi_prep_cif 3 , |
| +.Xr ffi_prep_cif_var 3 , |
| .Xr ffi_call 3 |
| Index: libffi/man/ffi_prep_cif.3 |
| =================================================================== |
| --- libffi.orig/man/ffi_prep_cif.3 |
| +++ libffi/man/ffi_prep_cif.3 |
| @@ -37,7 +37,9 @@ structs that describe the data type, siz |
| points to an |
| .Nm ffi_type |
| that describes the data type, size and alignment of the |
| -return value. |
| +return value. Note that to call a variadic function |
| +.Nm ffi_prep_cif_var |
| +must be used instead. |
| .Sh RETURN VALUES |
| Upon successful completion, |
| .Nm ffi_prep_cif |
| @@ -63,4 +65,6 @@ defined in |
| . |
| .Sh SEE ALSO |
| .Xr ffi 3 , |
| -.Xr ffi_call 3 |
| +.Xr ffi_call 3 , |
| +.Xr ffi_prep_cif_var 3 |
| + |
| Index: libffi/man/ffi_prep_cif_var.3 |
| =================================================================== |
| --- /dev/null |
| +++ libffi/man/ffi_prep_cif_var.3 |
| @@ -0,0 +1,73 @@ |
| +.Dd January 25, 2011 |
| +.Dt ffi_prep_cif_var 3 |
| +.Sh NAME |
| +.Nm ffi_prep_cif_var |
| +.Nd Prepare a |
| +.Nm ffi_cif |
| +structure for use with |
| +.Nm ffi_call |
| +for variadic functions. |
| +.Sh SYNOPSIS |
| +.In ffi.h |
| +.Ft ffi_status |
| +.Fo ffi_prep_cif_var |
| +.Fa "ffi_cif *cif" |
| +.Fa "ffi_abi abi" |
| +.Fa "unsigned int nfixedargs" |
| +.Fa "unsigned int ntotalargs" |
| +.Fa "ffi_type *rtype" |
| +.Fa "ffi_type **atypes" |
| +.Fc |
| +.Sh DESCRIPTION |
| +The |
| +.Nm ffi_prep_cif_var |
| +function prepares a |
| +.Nm ffi_cif |
| +structure for use with |
| +.Nm ffi_call |
| +for variadic functions. |
| +.Fa abi |
| +specifies a set of calling conventions to use. |
| +.Fa atypes |
| +is an array of |
| +.Fa ntotalargs |
| +pointers to |
| +.Nm ffi_type |
| +structs that describe the data type, size and alignment of each argument. |
| +.Fa rtype |
| +points to an |
| +.Nm ffi_type |
| +that describes the data type, size and alignment of the |
| +return value. |
| +.Fa nfixedargs |
| +must contain the number of fixed (non-variadic) arguments. |
| +Note that to call a non-variadic function |
| +.Nm ffi_prep_cif |
| +must be used. |
| +.Sh RETURN VALUES |
| +Upon successful completion, |
| +.Nm ffi_prep_cif_var |
| +returns |
| +.Nm FFI_OK . |
| +It will return |
| +.Nm FFI_BAD_TYPEDEF |
| +if |
| +.Fa cif |
| +is |
| +.Nm NULL |
| +or |
| +.Fa atypes |
| +or |
| +.Fa rtype |
| +is malformed. If |
| +.Fa abi |
| +does not refer to a valid ABI, |
| +.Nm FFI_BAD_ABI |
| +will be returned. Available ABIs are |
| +defined in |
| +.Nm <ffitarget.h> |
| +. |
| +.Sh SEE ALSO |
| +.Xr ffi 3 , |
| +.Xr ffi_call 3 , |
| +.Xr ffi_prep_cif 3 |
| Index: libffi/src/arm/ffi.c |
| =================================================================== |
| --- libffi.orig/src/arm/ffi.c |
| +++ libffi/src/arm/ffi.c |
| @@ -196,6 +196,18 @@ ffi_status ffi_prep_cif_machdep(ffi_cif |
| return FFI_OK; |
| } |
| |
| +/* Perform machine dependent cif processing for variadic calls */ |
| +ffi_status ffi_prep_cif_machdep_var(ffi_cif *cif, |
| + unsigned int nfixedargs, |
| + unsigned int ntotalargs) |
| +{ |
| + /* VFP variadic calls actually use the SYSV ABI */ |
| + if (cif->abi == FFI_VFP) |
| + cif->abi = FFI_SYSV; |
| + |
| + return ffi_prep_cif_machdep(cif); |
| +} |
| + |
| /* Prototypes for assembly functions, in sysv.S */ |
| extern void ffi_call_SYSV (void (*fn)(void), extended_cif *, unsigned, unsigned, unsigned *); |
| extern void ffi_call_VFP (void (*fn)(void), extended_cif *, unsigned, unsigned, unsigned *); |
| Index: libffi/src/arm/ffitarget.h |
| =================================================================== |
| --- libffi.orig/src/arm/ffitarget.h |
| +++ libffi/src/arm/ffitarget.h |
| @@ -55,6 +55,8 @@ typedef enum ffi_abi { |
| #define FFI_TYPE_STRUCT_VFP_FLOAT (FFI_TYPE_LAST + 1) |
| #define FFI_TYPE_STRUCT_VFP_DOUBLE (FFI_TYPE_LAST + 2) |
| |
| +#define FFI_TARGET_SPECIFIC_VARIADIC |
| + |
| /* ---- Definitions for closures ----------------------------------------- */ |
| |
| #define FFI_CLOSURES 1 |
| @@ -62,4 +64,3 @@ typedef enum ffi_abi { |
| #define FFI_NATIVE_RAW_API 0 |
| |
| #endif |
| - |
| Index: libffi/src/cris/ffi.c |
| =================================================================== |
| --- libffi.orig/src/cris/ffi.c |
| +++ libffi/src/cris/ffi.c |
| @@ -153,21 +153,24 @@ ffi_prep_args (char *stack, extended_cif |
| return (struct_count); |
| } |
| |
| -ffi_status |
| -ffi_prep_cif (ffi_cif * cif, |
| - ffi_abi abi, unsigned int nargs, |
| - ffi_type * rtype, ffi_type ** atypes) |
| +ffi_status FFI_HIDDEN |
| +ffi_prep_cif_core (ffi_cif * cif, |
| + ffi_abi abi, unsigned int isvariadic, |
| + unsigned int nfixedargs, unsigned int ntotalargs, |
| + ffi_type * rtype, ffi_type ** atypes) |
| { |
| unsigned bytes = 0; |
| unsigned int i; |
| ffi_type **ptr; |
| |
| FFI_ASSERT (cif != NULL); |
| + FFI_ASSERT((!isvariadic) || (nfixedargs >= 1)); |
| + FFI_ASSERT(nfixedargs <= ntotalargs); |
| FFI_ASSERT (abi > FFI_FIRST_ABI && abi < FFI_LAST_ABI); |
| |
| cif->abi = abi; |
| cif->arg_types = atypes; |
| - cif->nargs = nargs; |
| + cif->nargs = ntotalargs; |
| cif->rtype = rtype; |
| |
| cif->flags = 0; |
| Index: libffi/src/prep_cif.c |
| =================================================================== |
| --- libffi.orig/src/prep_cif.c |
| +++ libffi/src/prep_cif.c |
| @@ -90,14 +90,27 @@ static ffi_status initialize_aggregate(f |
| /* Perform machine independent ffi_cif preparation, then call |
| machine dependent routine. */ |
| |
| -ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi, unsigned int nargs, |
| - ffi_type *rtype, ffi_type **atypes) |
| +/* For non variadic functions isvariadic should be 0 and |
| + nfixedargs==ntotalargs. |
| + |
| + For variadic calls, isvariadic should be 1 and nfixedargs |
| + and ntotalargs set as appropriate. nfixedargs must always be >=1 */ |
| + |
| + |
| +ffi_status FFI_HIDDEN ffi_prep_cif_core(ffi_cif *cif, ffi_abi abi, |
| + unsigned int isvariadic, |
| + unsigned int nfixedargs, |
| + unsigned int ntotalargs, |
| + ffi_type *rtype, ffi_type **atypes) |
| { |
| unsigned bytes = 0; |
| unsigned int i; |
| ffi_type **ptr; |
| |
| FFI_ASSERT(cif != NULL); |
| + FFI_ASSERT((!isvariadic) || (nfixedargs >= 1)); |
| + FFI_ASSERT(nfixedargs <= ntotalargs); |
| + |
| #ifndef X86_WIN32 |
| if ((abi > FFI_FIRST_ABI) && (abi <= FFI_DEFAULT_ABI)) |
| return FFI_BAD_ABI; |
| @@ -108,7 +121,7 @@ ffi_status ffi_prep_cif(ffi_cif *cif, ff |
| |
| cif->abi = abi; |
| cif->arg_types = atypes; |
| - cif->nargs = nargs; |
| + cif->nargs = ntotalargs; |
| cif->rtype = rtype; |
| |
| cif->flags = 0; |
| @@ -164,10 +177,31 @@ ffi_status ffi_prep_cif(ffi_cif *cif, ff |
| cif->bytes = bytes; |
| |
| /* Perform machine dependent cif processing */ |
| +#ifdef FFI_TARGET_SPECIFIC_VARIADIC |
| + if (isvariadic) |
| + return ffi_prep_cif_machdep_var(cif, nfixedargs, ntotalargs); |
| +#endif |
| + |
| return ffi_prep_cif_machdep(cif); |
| } |
| #endif /* not __CRIS__ */ |
| |
| +ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi, unsigned int nargs, |
| + ffi_type *rtype, ffi_type **atypes) |
| +{ |
| + return ffi_prep_cif_core(cif, abi, 0, nargs, nargs, rtype, atypes); |
| +} |
| + |
| +ffi_status ffi_prep_cif_var(ffi_cif *cif, |
| + ffi_abi abi, |
| + unsigned int nfixedargs, |
| + unsigned int ntotalargs, |
| + ffi_type *rtype, |
| + ffi_type **atypes) |
| +{ |
| + return ffi_prep_cif_core(cif, abi, 1, nfixedargs, ntotalargs, rtype, atypes); |
| +} |
| + |
| #if FFI_CLOSURES |
| |
| ffi_status |
| Index: libffi/testsuite/libffi.call/cls_double_va.c |
| =================================================================== |
| --- libffi.orig/testsuite/libffi.call/cls_double_va.c |
| +++ libffi/testsuite/libffi.call/cls_double_va.c |
| @@ -37,7 +37,8 @@ int main (void) |
| arg_types[1] = &ffi_type_double; |
| arg_types[2] = NULL; |
| |
| - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ffi_type_sint, |
| + /* This printf call is variadic */ |
| + CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2, &ffi_type_sint, |
| arg_types) == FFI_OK); |
| |
| args[0] = &format; |
| @@ -49,6 +50,9 @@ int main (void) |
| printf("res: %d\n", (int) res); |
| // { dg-output "\nres: 4" } |
| |
| + /* The call to cls_double_va_fn is static, so have to use a normal prep_cif */ |
| + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ffi_type_sint, arg_types) == FFI_OK); |
| + |
| CHECK(ffi_prep_closure_loc(pcl, &cif, cls_double_va_fn, NULL, code) == FFI_OK); |
| |
| res = ((int(*)(char*, double))(code))(format, doubleArg); |
| Index: libffi/testsuite/libffi.call/cls_longdouble_va.c |
| =================================================================== |
| --- libffi.orig/testsuite/libffi.call/cls_longdouble_va.c |
| +++ libffi/testsuite/libffi.call/cls_longdouble_va.c |
| @@ -37,7 +37,8 @@ int main (void) |
| arg_types[1] = &ffi_type_longdouble; |
| arg_types[2] = NULL; |
| |
| - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ffi_type_sint, |
| + /* This printf call is variadic */ |
| + CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2, &ffi_type_sint, |
| arg_types) == FFI_OK); |
| |
| args[0] = &format; |
| @@ -49,6 +50,10 @@ int main (void) |
| printf("res: %d\n", (int) res); |
| // { dg-output "\nres: 4" } |
| |
| + /* The call to cls_longdouble_va_fn is static, so have to use a normal prep_cif */ |
| + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ffi_type_sint, |
| + arg_types) == FFI_OK); |
| + |
| CHECK(ffi_prep_closure_loc(pcl, &cif, cls_longdouble_va_fn, NULL, code) == FFI_OK); |
| |
| res = ((int(*)(char*, long double))(code))(format, ldArg); |
| Index: libffi/testsuite/libffi.call/float_va.c |
| =================================================================== |
| --- /dev/null |
| +++ libffi/testsuite/libffi.call/float_va.c |
| @@ -0,0 +1,107 @@ |
| +/* Area: fp and variadics |
| + Purpose: check fp inputs and returns work on variadics, even the fixed params |
| + Limitations: None |
| + PR: none |
| + Originator: <david.gilbert@linaro.org> 2011-01-25 |
| + |
| + Intended to stress the difference in ABI on ARM vfp |
| +*/ |
| + |
| +/* { dg-do run } */ |
| + |
| +#include <stdarg.h> |
| + |
| +#include "ffitest.h" |
| + |
| +/* prints out all the parameters, and returns the sum of them all. |
| + * 'x' is the number of variadic parameters all of which are double in this test |
| + */ |
| +double float_va_fn(unsigned int x, double y,...) |
| +{ |
| + double total=0.0; |
| + va_list ap; |
| + unsigned int i; |
| + |
| + total+=(double)x; |
| + total+=y; |
| + |
| + printf("%u: %.1lf :", x, y); |
| + |
| + va_start(ap, y); |
| + for(i=0;i<x;i++) |
| + { |
| + double arg=va_arg(ap, double); |
| + total+=arg; |
| + printf(" %d:%.1lf ", i, arg); |
| + } |
| + va_end(ap); |
| + |
| + printf(" total: %.1lf\n", total); |
| + |
| + return total; |
| +} |
| + |
| +int main (void) |
| +{ |
| + ffi_cif cif; |
| + |
| + ffi_type *arg_types[5]; |
| + void *values[5]; |
| + double doubles[5]; |
| + unsigned int firstarg; |
| + double resfp; |
| + |
| + /* First test, pass float_va_fn(0,2.0) - note there are no actual |
| + * variadic parameters, but it's declared variadic so the ABI may be |
| + * different. */ |
| + /* Call it statically and then via ffi */ |
| + resfp=float_va_fn(0,2.0); |
| + // { dg-output "0: 2.0 : total: 2.0" } |
| + printf("compiled: %.1lf\n", resfp); |
| + // { dg-output "\ncompiled: 2.0" } |
| + |
| + arg_types[0] = &ffi_type_uint; |
| + arg_types[1] = &ffi_type_double; |
| + arg_types[2] = NULL; |
| + CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 2, 2, |
| + &ffi_type_double, arg_types) == FFI_OK); |
| + |
| + firstarg = 0; |
| + doubles[0] = 2.0; |
| + values[0] = &firstarg; |
| + values[1] = &doubles[0]; |
| + ffi_call(&cif, FFI_FN(float_va_fn), &resfp, values); |
| + // { dg-output "\n0: 2.0 : total: 2.0" } |
| + printf("ffi: %.1lf\n", resfp); |
| + // { dg-output "\nffi: 2.0" } |
| + |
| + /* Second test, float_va_fn(2,2.0,3.0,4.0), now with variadic params */ |
| + /* Call it statically and then via ffi */ |
| + resfp=float_va_fn(2,2.0,3.0,4.0); |
| + // { dg-output "\n2: 2.0 : 0:3.0 1:4.0 total: 11.0" } |
| + printf("compiled: %.1lf\n", resfp); |
| + // { dg-output "\ncompiled: 11.0" } |
| + |
| + arg_types[0] = &ffi_type_uint; |
| + arg_types[1] = &ffi_type_double; |
| + arg_types[2] = &ffi_type_double; |
| + arg_types[3] = &ffi_type_double; |
| + arg_types[4] = NULL; |
| + CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 2, 4, |
| + &ffi_type_double, arg_types) == FFI_OK); |
| + |
| + firstarg = 2; |
| + doubles[0] = 2.0; |
| + doubles[1] = 3.0; |
| + doubles[2] = 4.0; |
| + values[0] = &firstarg; |
| + values[1] = &doubles[0]; |
| + values[2] = &doubles[1]; |
| + values[3] = &doubles[2]; |
| + ffi_call(&cif, FFI_FN(float_va_fn), &resfp, values); |
| + // { dg-output "\n2: 2.0 : 0:3.0 1:4.0 total: 11.0" } |
| + printf("ffi: %.1lf\n", resfp); |
| + // { dg-output "\nffi: 11.0" } |
| + |
| + exit(0); |
| +} |
| Index: libffi/doc/libffi.texi |
| =================================================================== |
| --- libffi.orig/doc/libffi.texi |
| +++ libffi/doc/libffi.texi |
| @@ -19,7 +19,7 @@ |
| This manual is for Libffi, a portable foreign-function interface |
| library. |
| |
| -Copyright @copyright{} 2008, 2010 Red Hat, Inc. |
| +Copyright @copyright{} 2008, 2010, 2011 Red Hat, Inc. |
| |
| @quotation |
| Permission is granted to copy, distribute and/or modify this document |
| @@ -133,8 +133,6 @@ This initializes @var{cif} according to |
| you want. @ref{Multiple ABIs} for more information. |
| |
| @var{nargs} is the number of arguments that this function accepts. |
| -@samp{libffi} does not yet handle varargs functions; see @ref{Missing |
| -Features} for more information. |
| |
| @var{rtype} is a pointer to an @code{ffi_type} structure that |
| describes the return type of the function. @xref{Types}. |
| @@ -150,6 +148,30 @@ objects is incorrect; or @code{FFI_BAD_A |
| is invalid. |
| @end defun |
| |
| +If the function being called is variadic (varargs) then |
| +@code{ffi_prep_cif_var} must be used instead of @code{ffi_prep_cif}. |
| + |
| +@findex ffi_prep_cif_var |
| +@defun ffi_status ffi_prep_cif_var (ffi_cif *@var{cif}, ffi_abi var{abi}, unsigned int @var{nfixedargs}, unsigned int var{ntotalargs}, ffi_type *@var{rtype}, ffi_type **@var{argtypes}) |
| +This initializes @var{cif} according to the given parameters for |
| +a call to a variadic function. In general it's operation is the |
| +same as for @code{ffi_prep_cif} except that: |
| + |
| +@var{nfixedargs} is the number of fixed arguments, prior to any |
| +variadic arguments. It must be greater than zero. |
| + |
| +@var{ntotalargs} the total number of arguments, including variadic |
| +and fixed arguments. |
| + |
| +Note that, different cif's must be prepped for calls to the same |
| +function when different numbers of arguments are passed. |
| + |
| +Also note that a call to @code{ffi_prep_cif_var} with |
| +@var{nfixedargs}=@var{nototalargs} is NOT equivalent to a call to |
| +@code{ffi_prep_cif}. |
| + |
| +@end defun |
| + |
| |
| To call a function using an initialized @code{ffi_cif}, use the |
| @code{ffi_call} function: |
| @@ -572,9 +594,7 @@ support for these. |
| |
| @itemize @bullet |
| @item |
| -There is no support for calling varargs functions. This may work on |
| -some platforms, depending on how the ABI is defined, but it is not |
| -reliable. |
| +Variadic closures. |
| |
| @item |
| There is no support for bit fields in structures. |
| @@ -591,6 +611,8 @@ The ``raw'' API is undocumented. |
| @c anything else? |
| @end itemize |
| |
| +Note that variadic support is very new and tested on a relatively |
| +small number of platforms. |
| |
| @node Index |
| @unnumbered Index |
| Index: libffi/ChangeLog |
| =================================================================== |
| --- libffi.orig/ChangeLog |
| +++ libffi/ChangeLog |
| @@ -59,6 +59,17 @@ |
| |
| * configure: Regenerate. |
| |
| +2011-11-12 David Gilbert <david.gilbert@linaro.org> |
| + |
| + * doc/libffi.texi, include/ffi.h.in, include/ffi_common.h, |
| + man/Makefile.am, man/ffi.3, man/ffi_prep_cif.3, |
| + man/ffi_prep_cif_var.3, src/arm/ffi.c, src/arm/ffitarget.h, |
| + src/cris/ffi.c, src/prep_cif.c, |
| + testsuite/libffi.call/cls_double_va.c, |
| + testsuite/libffi.call/cls_longdouble_va.c, |
| + testsuite/libffi.call/float_va.c: Many changes to support variadic |
| + function calls. |
| + |
| 2011-11-12 Kyle Moffett <Kyle.D.Moffett@boeing.com> |
| |
| * src/powerpc/ffi.c, src/powerpc/ffitarget.h, |