I've been looking into some libffi test failures on netbsd/ppc. To make
a long story short, under some circumstances (returning a small
aggregate that's not a multiple of 4 bytes), ffi_call() will write past
the end of the buffer passed to rvalue.
In the cls_6byte.c test, this manifests itself as the first field in
g_dbl getting mysteriously set to zero after the call to ffi_call() in
main, since g_dbl is allocated after res_dbl with no padding. (This
surprised me a little, but the debugger confirms that &g_dbl is six
bytes higher than &res_dbl.) As a result, the *next* test in that file
will fail, since g_dbl no longer has the expected value.
The actual clobbering takes place at this point in src/powerpc/sysv.S:
> L(smst_8byte):
> stw %r3,0(%r30)
> stw %r4,4(%r30)
> b L(done_return_value)
where r30 contains 'rvalue'. This ends up writing 8 bytes even for a
6-byte return struct.
I'm not familiar enough with ppc assembly to suggest a patch; I'm not
really sure what the code immediately before the smst_8byte label is
doing. One idea is to do a read-modify-write and use insrwi/rlwinm to
modify only the portion of the word containing the returned struct. But
the struct may be aligned at the end of a memory region, so maybe the
only correct implementation for oddly-sized aggregates is a sequence of
rotates and stswi or stbu instructions.
regards
Wim Lewis / wiml@hhhh.org