public inbox for libffi-discuss@sourceware.org
 help / color / mirror / Atom feed
From: "Kaz Kylheku (libffi)" <382-725-6798@kylheku.com>
To: Bruno Haible <bruno@clisp.org>
Cc: libffi-discuss@sourceware.org
Subject: Re: test results on many platforms
Date: Sun, 22 Oct 2017 18:28:00 -0000	[thread overview]
Message-ID: <d0041aa4ade72ea0f4e1d6693b283385@mail.kylheku.com> (raw)
In-Reply-To: <2437301.0N14NqkuRT@omega>

Hi Bruno,

I suspect that some of your ffi_call bug reports on 64 bits may be 
invalid.

The return value on 64 bits, of small types, requires special treatment
due to known quirk/design flaw in the API. It was originally not 
documented,
and then it was just documented as is. The way your code is doing it
is how it *should* be, but isn't.

Firstly, you must allocate a full "ffi_arg" word for the return value.
You can't just use a &int_variable pointer for the return value of
type int. The "ffi_arg" is in fact a 64 bit word.

Secondly, the return value comes out aligned funny inside this word on
big endian platforms. It is not at the base address as it would be
on little endian, but rather the value of the wider ffi_arg word is
the return value: in other words, the "int" is in the high order bytes
which are four bytes above the base address.

This situation bears some resemblance to promotion in the C language!
Or, rather, not the type promotion from char/short to int as much as
the widening in old-style calls: how char and short arguments are 
actually
int arguments:

    int old_style(arg)
    char arg;
    {
      /*...*/
    }

the argument is really of type int. When we call old_style((char) 42),
promotion dove-tails with this: the char expression promotes to int,
and so the correct call is generated, nonexistence of prototype
notwithstanding.

In libffi return value passage, every integer type smaller than ffi_arg
is "promoted" to ffi_arg.

Naively written code will appear to work fine on little endian 64 bit,
such as x86_64, and then flop on, say, PPC64.

I ran into this in the TXR Lisp FFI, resulting in this commit:

http://www.kylheku.com/cgit/txr/commit/ffi.c?id=10507446389cff9b072c25aa86ba35834a786fe5

My FFI type systems's virtual functions for doing "put" and "get" memory
operations had to be split into "put", "rput", "get" and "rget" with the
"r" variants doing  the right thing for return values. The pad_retval
macro calculates a padded size for any given type if it is used as a
return value.

Many thanks to the helpful hints from this mailing list.

  parent reply	other threads:[~2017-10-22 18:28 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-10-21 18:31 Bruno Haible
2017-10-22  8:12 ` Matthias Klose
2017-10-22 14:58   ` Bruno Haible
2017-10-22 18:28 ` Kaz Kylheku (libffi) [this message]
2017-10-22 20:33   ` small return types Bruno Haible
2017-10-22 21:38     ` Kaz Kylheku (libffi)
2017-10-25  5:18     ` Tom Tromey

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=d0041aa4ade72ea0f4e1d6693b283385@mail.kylheku.com \
    --to=382-725-6798@kylheku.com \
    --cc=bruno@clisp.org \
    --cc=libffi-discuss@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).