* libffi fixes for ARM EABI
@ 2007-08-10 16:03 Andrew Haley
0 siblings, 0 replies; only message in thread
From: Andrew Haley @ 2007-08-10 16:03 UTC (permalink / raw)
To: java-patches, gcc-patches
I found quite a few bugs in libffi: fixed thusly. Now, everything
passes except the unwind tests, which I am working on.
Andrew.
2007-08-10 Andrew Haley <aph@redhat.com>
* src/arm/ffi.c (ffi_prep_args): Align structs by at least 4 bytes.
Only treat r0 as a struct address if we're actually returning a
struct by address.
Only copy the bytes that are actually within a struct.
(ffi_prep_cif_machdep): A Composite Type not larger than 4 bytes
is returned in r0, not passed by address.
(ffi_call): Allocate a word-sized temporary for the case where
a composite is returned in r0.
(ffi_prep_incoming_args_SYSV): Align as necessary.
Index: ffi.c
===================================================================
--- ffi.c (revision 127334)
+++ ffi.c (working copy)
@@ -40,7 +40,7 @@
argp = stack;
- if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT ) {
+ if ( ecif->cif->flags == FFI_TYPE_STRUCT ) {
*(void **) argp = ecif->rvalue;
argp += 4;
}
@@ -58,6 +58,9 @@
argp = (char *) ALIGN(argp, (*p_arg)->alignment);
}
+ if ((*p_arg)->type == FFI_TYPE_STRUCT)
+ argp = (char *) ALIGN(argp, 4);
+
z = (*p_arg)->size;
if (z < sizeof(int))
{
@@ -81,7 +84,7 @@
break;
case FFI_TYPE_STRUCT:
- *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+ memcpy(argp, *p_argv, (*p_arg)->size);
break;
default:
@@ -115,7 +118,6 @@
switch (cif->rtype->type)
{
case FFI_TYPE_VOID:
- case FFI_TYPE_STRUCT:
case FFI_TYPE_FLOAT:
case FFI_TYPE_DOUBLE:
cif->flags = (unsigned) cif->rtype->type;
@@ -126,6 +128,17 @@
cif->flags = (unsigned) FFI_TYPE_SINT64;
break;
+ case FFI_TYPE_STRUCT:
+ if (cif->rtype->size <= 4)
+ /* A Composite Type not larger than 4 bytes is returned in r0. */
+ cif->flags = (unsigned)FFI_TYPE_INT;
+ else
+ /* A Composite Type larger than 4 bytes, or whose size cannot
+ be determined statically ... is stored in memory at an
+ address passed [in r0]. */
+ cif->flags = (unsigned)FFI_TYPE_STRUCT;
+ break;
+
default:
cif->flags = FFI_TYPE_INT;
break;
@@ -141,21 +154,27 @@
{
extended_cif ecif;
+ int small_struct = (cif->flags == FFI_TYPE_INT
+ && cif->rtype->type == FFI_TYPE_STRUCT);
+
ecif.cif = cif;
ecif.avalue = avalue;
+
+ 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 */
if ((rvalue == NULL) &&
- (cif->rtype->type == FFI_TYPE_STRUCT))
+ (cif->flags == FFI_TYPE_STRUCT))
{
ecif.rvalue = alloca(cif->rtype->size);
}
+ else if (small_struct)
+ ecif.rvalue = &temp;
else
ecif.rvalue = rvalue;
-
-
+
switch (cif->abi)
{
case FFI_SYSV:
@@ -167,6 +186,8 @@
FFI_ASSERT(0);
break;
}
+ if (small_struct)
+ memcpy (rvalue, &temp, cif->rtype->size);
}
/** private members **/
@@ -228,9 +249,12 @@
{
size_t z;
+ size_t alignment = (*p_arg)->alignment;
+ if (alignment < 4)
+ alignment = 4;
/* Align if necessary */
- if ((sizeof(int) - 1) & (unsigned) argp) {
- argp = (char *) ALIGN(argp, sizeof(int));
+ if ((alignment - 1) & (unsigned) argp) {
+ argp = (char *) ALIGN(argp, alignment);
}
z = (*p_arg)->size;
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2007-08-10 16:03 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-08-10 16:03 libffi fixes for ARM EABI Andrew Haley
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).