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: closure api return value types problem


On Fri, 02 Apr 2010 09:40:31 +0100
Andrew Haley <aph@redhat.com> wrote:

> > Just looked at cls_ushort.c(and other integrals) test:
> >   *(ffi_arg*)resp = *(unsigned short *)args[0];
> > and cls_float.c
> >    *(float *)resp = *(float *)args[0];
> > 
> > Integrals seem to strangely be casted to 'ffi_arg *'(long *) while FPU ones
> > are casted to their real type. It's normal (but undocumented) or it's a
> > horrible inconsistency bug?
> 
> If you came up with a small self-contained test case it'd help a lot.

What kind of test you would like to see?
The tests are in libffi tree and they all work correctly (even on ppc64):
testsuite/libffi.call/cls_ushort.c
testsuite/libffi.call/cls_float.c
testsuite/libffi.call/cls_ulonglong.c

But! The thing I don't understand is why libffi treats ushort, uint
retval types (and _only_ retval types!) so specifically?

Let's consider cls_ushort.c test.
resp pointer holds address to perfectly aligned storage, so we can write
there any save value by casting resp to appropriate type.
I (and not only me) expected to see following code there (in cls_ushort test):
    *(unsigned int *)resp = *(unsigned int *)args[0];
but it uses following construct:
    *(ffi_arg *)resp = *(unsigned int *)args[0];

And I don't see why it casts resp to 'ffi_arg*'.

For example powerpc64 big endian code looks unordinary, when handles
uint8, uint16, uint32 retvals.
src/powerpc/linux64_closure.S:
...
.Lret_type0:
# case FFI_TYPE_VOID
        mtlr %r0
        addi %r1, %r1, 240
        blr
        nop
# case FFI_TYPE_INT
        lwa %r3, 112+4(%r1) ########## +4! (8-4). hmm...
        mtlr %r0
        addi %r1, %r1, 240
        blr
# case FFI_TYPE_FLOAT
        lfs %f1, 112+0(%r1) ########## all ok. normall address
        mtlr %r0
        addi %r1, %r1, 240
        blr
# case FFI_TYPE_DOUBLE
        lfd %f1, 112+0(%r1) ########## all ok. normall address
        mtlr %r0
        addi %r1, %r1, 240
        blr
# case FFI_TYPE_LONGDOUBLE
        lfd %f1, 112+0(%r1) ########## all ok. normall address
        mtlr %r0
        lfd %f2, 112+8(%r1)
        b .Lfinish
# case FFI_TYPE_UINT8
        lbz %r3, 112+7(%r1) ########## +7! (8-1) hmm...
        mtlr %r0
        addi %r1, %r1, 240
        blr
# case FFI_TYPE_SINT8
        lbz %r3, 112+7(%r1) ########## +7! (8-1) hmm...
        extsb %r3,%r3
        mtlr %r0
        b .Lfinish
...
The fun thing 'args' are aligned properly and they just need pointer cast:
(src/powerpc/ffi.c:ffi_closure_helper_LINUX64)

Do you want me to show a patch for tests, which
will look more logical from ABI standpoint, but
will break all big endian platforms?

Thanks!

> Andrew.
> 
-- 

  Sergei

Attachment: signature.asc
Description: PGP signature


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