++2013-11-02 Mischa Jonker <mjonker@synopsys.com>
++
++ * Makefile.am (nodist_libffi_la_SOURCES): Fix build error.
++ * Makefile.in: Rebuilt.
++
++2013-11-02 David Schneider <david.schneider@bivab.de>
++
++ * src/arm/ffi.c: more robust argument handling for closures on arm hardfloat
++ * testsuite/libffi.call/many_mixed.c: New file.
++ * testsuite/libffi.call/cls_many_mixed_args.c: More tests.
++
+2013-11-02 Vitaly Budovski
+
+ * src/x86/ffi.c (ffi_prep_cif_machdep): Don't align stack for win32.
+
+2013-10-23 Mark H Weaver <mhw@netris.org>
+
+ * src/mips/ffi.c: Fix handling of uint32_t arguments on the
+ MIPS N32 ABI.
+
+2013-10-13 Sandra Loosemore <sandra@codesourcery.com>
+
+ * README: Add Nios II to table of supported platforms.
+ * Makefile.am (EXTRA_DIST): Add nios2 files.
+ (nodist_libffi_la_SOURCES): Likewise.
+ * Makefile.in: Regenerated.
+ * configure.ac (nios2*-linux*): New host.
+ (NIOS2): Add AM_CONDITIONAL.
+ * configure: Regenerated.
+ * src/nios2/ffi.c: New.
+ * src/nios2/ffitarget.h: New.
+ * src/nios2/sysv.S: New.
+ * src/prep_cif.c (initialize_aggregate): Handle extra structure
+ alignment via FFI_AGGREGATE_ALIGNMENT.
+ (ffi_prep_cif_core): Conditionalize structure return for NIOS2.
+
+2013-10-10 Sandra Loosemore <sandra@codesourcery.com>
+
+ * testsuite/libffi.call/cls_many_mixed_args.c (cls_ret_double_fn):
+ Fix uninitialized variable.
+
+2013-10-11 Marcus Shawcroft <marcus.shawcroft@arm.com>
+
+ * testsuite/libffi.call/many.c (many): Replace * with +.
+
+2013-10-08 Ondřej Bílka <neleai@seznam.cz>
+
+ * src/aarch64/ffi.c, src/aarch64/sysv.S, src/arm/ffi.c,
+ src/arm/gentramp.sh, src/bfin/sysv.S, src/closures.c,
+ src/dlmalloc.c, src/ia64/ffi.c, src/microblaze/ffi.c,
+ src/microblaze/sysv.S, src/powerpc/darwin_closure.S,
+ src/powerpc/ffi.c, src/powerpc/ffi_darwin.c, src/sh/ffi.c,
+ src/tile/tile.S, testsuite/libffi.call/nested_struct11.c: Fix
+ spelling errors.
+
+2013-10-08 Anthony Green <green@moxielogic.com>
+
+ * aclocal.m4, compile, config.guess, config.sub, depcomp,
+ install-sh, mdate-sh, missing, texinfo.tex: Update from upstream.
+ * configure.ac: Update version to 3.0.14-rc0.
+ * Makefile.in, configure, Makefile.in, include/Makefile.in,
+ man/Makefile.in, testsuite/Makefile.in: Rebuilt.
+ * README: Mention M88K and VAX.
+
+2013-07-15 Miod Vallat <miod@openbsd.org>
+
+ * Makefile.am,
+ configure.ac,
+ src/m88k/ffi.c,
+ src/m88k/ffitarget.h,
+ src/m88k/obsd.S,
+ src/vax/elfbsd.S,
+ src/vax/ffi.c,
+ src/vax/ffitarget.h: Add m88k and vax support.
+
+2013-06-24 Alan Modra <amodra@gmail.com>
+
+ * src/powerpc/ffi.c (ffi_prep_args_SYSV): Move var declaration
+ before statements.
+ (ffi_prep_args64): Support little-endian.
+ (ffi_closure_helper_SYSV, ffi_closure_helper_LINUX64): Likewise.
+ * src/powerpc/linux64_closure.S (ffi_closure_LINUX64): Likewise.
+ * src/powerpc/ppc_closure.S (ffi_closure_SYSV): Likewise.
+
2013-06-12 Mischa Jonker <mjonker@synopsys.com>
* configure.ac: Add support for ARC.
Copyright (c) 2011 Anthony Green
Copyright (c) 2011 Free Software Foundation
Copyright (c) 1998, 2008, 2011 Red Hat, Inc.
--
-- ARM Foreign Function Interface
++
++ ARM Foreign Function Interface
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
unsigned int temp;
/* If the return value is a struct and we don't have a return */
-- /* value address then we need to make one */
++ /* value address then we need to make one */
if ((rvalue == NULL) &&
(cif->flags == FFI_TYPE_STRUCT))
p_argv++;
regp = tregp + z;
-- /* if regp points above the end of the register area */
++ // if we read past the last core register, make sure we have not read
++ // from the stack before and continue reading after regp
++ if(regp > eo_regp)
++ {
++ if(stack_used)
++ {
++ abort(); // we should never read past the end of the register
++ // are if the stack is already in use
++ }
++ argp = regp;
++ }
if(regp >= eo_regp)
{
-- /* sanity check that we haven't read from the stack area before
-- * reaching this point */
-- FFI_ASSERT(argp <= regp);
-- FFI_ASSERT(argp == stack + 16);
-- argp = regp;
-- done_with_regs = 1;
-- stack_used = 1;
++ done_with_regs = 1;
++ stack_used = 1;
}
-- continue;
++ continue;
}
}
stack_used = 1;
#endif
else
return FFI_BAD_ABI;
--
++
#if FFI_EXEC_TRAMPOLINE_TABLE
void **config = FFI_TRAMPOLINE_CODELOC_CONFIG(codeloc);
config[0] = closure;
#include <float.h>
#include <math.h>
--#define NARGS 12
++#define NARGS 16
static void cls_ret_double_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
double t;
for(i = 0; i < NARGS; i++)
{
-- if(i == 8)
++ if(i == 4 || i == 9 || i == 11 || i == 13 || i == 15)
{
t = *(long int *)args[i];
CHECK(t == i+1);
}
*(double *)resp = r;
}
--typedef double (*cls_ret_double)(double, double, double, double, double, double, double, double, long int, double, double, double);
++typedef double (*cls_ret_double)(double, double, double, double, long int,
++double, double, double, double, long int, double, long int, double, long int,
++double, long int);
int main (void)
{
ffi_type * cl_arg_types[NARGS];
double res;
int i;
-- double expected = 15.9;
++ double expected = 64.9;
for(i = 0; i < NARGS; i++)
{
-- if(i == 8)
++ if(i == 4 || i == 9 || i == 11 || i == 13 || i == 15)
cl_arg_types[i] = &ffi_type_slong;
else
cl_arg_types[i] = &ffi_type_double;
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_double_fn, NULL, code) == FFI_OK);
-- res = (((cls_ret_double)code))(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 9,
-- 1.0, 1.1, 1.2);
++ res = (((cls_ret_double)code))(0.1, 0.2, 0.3, 0.4, 5, 0.6, 0.7, 0.8, 0.9, 10,
++ 1.1, 12, 1.3, 14, 1.5, 16);
if (abs(res - expected) < FLT_EPSILON)
exit(0);
else
--- /dev/null
--- /dev/null
++/* Area: ffi_call
++ Purpose: Check return value double, with many arguments
++ Limitations: none.
++ PR: none.
++ Originator: From the original ffitest.c */
++
++/* { dg-do run } */
++#include "ffitest.h"
++
++#include <stdlib.h>
++#include <float.h>
++#include <math.h>
++
++static double many(double f1,
++ double f2,
++ long int i1,
++ double f3,
++ double f4,
++ long int i2,
++ double f5,
++ double f6,
++ long int i3,
++ double f7,
++ double f8,
++ long int i4,
++ double f9,
++ double f10,
++ long int i5,
++ double f11,
++ double f12,
++ long int i6,
++ double f13)
++{
++ return ((double) (i1 + i2 + i3 + i4 + i5 + i6) + (f1/f2+f3/f4+f5/f6+f7/f8+f9/f10+f11/f12) * f13);
++}
++
++int main (void)
++{
++ ffi_cif cif;
++ ffi_type *args[19];
++ void *values[19];
++ double fa[19];
++ long int la[19];
++ double f, ff;
++ int i;
++
++ for (i = 0; i < 19; i++)
++ {
++ if( (i - 2) % 3 == 0) {
++ args[i] = &ffi_type_slong;
++ la[i] = (long int) i;
++ values[i] = &la[i];
++ }
++ else {
++ args[i] = &ffi_type_double;
++ fa[i] = (double) i;
++ values[i] = &fa[i];
++ }
++ }
++
++ /* Initialize the cif */
++ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 19,
++ &ffi_type_double, args) == FFI_OK);
++
++ ffi_call(&cif, FFI_FN(many), &f, values);
++
++ ff = many(fa[0], fa[1], la[2],
++ fa[3], fa[4], la[5],
++ fa[6], fa[7], la[8],
++ fa[9], fa[10], la[11],
++ fa[12], fa[13], la[14],
++ fa[15], fa[16], la[17],
++ fa[18]);
++ if (fabs(f - ff) < FLT_EPSILON)
++ exit(0);
++ else
++ abort();
++}