public inbox for libffi-discuss@sourceware.org
 help / color / mirror / Atom feed
From: "Damien Thébault" <damien@dtbo.net>
To: libffi-discuss@sourceware.org
Subject: Floating-point variadic function call
Date: Mon, 10 Oct 2016 07:04:00 -0000	[thread overview]
Message-ID: <20161010070352.GA11072@han> (raw)

[-- Attachment #1: Type: text/plain, Size: 1240 bytes --]

Hello,

I am trying to use libffi to call various functions, and my first try
was with printf(). As this is a variadic function, I used
ffi_prep_cif_var(). Everything seems to be working, except with floats,
which are not working, and are even generating wrong memory accesses
(detected by valgrind).

A similar function with ffi_prep_cif() and floats is working properly.

Could type promotion from float to double be the issue here ?
Does libffi handle type promotion in variadic calls or is it the
caller's job ?

I tested on a x86_64 computer both 64-bit and 32-bit versions (the
latter compiled with -m32) as well as ARM under qemu.
In all those cases, I didn't get the proper result with floats while
doubles are ok, as well as chars.
I've attached a sample source file that reproduces the problem and here
is the output of one test run:

 $ gcc $(pkg-config --cflags --libs libffi) -std=c99 -pedantic -Wall -Wextra libffi_variadic_printf.c -o libffi_variadic_printf
 $ ./libffi_variadic_printf
Non-variadic call:
[1.100000,2.200000,3.300000,4.400000,5.500000,6.600000,7.700000,8.800000,9.900000]
result is 83
Variadic call:
[0.000000,0.000000,0.000000,0.000000,0.000000,91750.390826,0.000000,0.000000,0.000000]
result is 87

Thanks,

[-- Attachment #2: libffi_variadic_printf.c --]
[-- Type: text/x-c, Size: 2018 bytes --]


#include <stdio.h>
#include <ffi.h>

int print9float(const char *fmt,
                float f1, float f2, float f3, float f4, float f5,
                float f6, float f7, float f8, float f9)
{
    return printf(fmt, f1, f2, f3, f4, f5, f6, f7, f8, f9);
}

void test_float()
{
    size_t i;
    ffi_cif cif;
    ffi_type *arg_types[10];
    void     *arg_values[10];
    char *fmt = "[%f,%f,%f,%f,%f,%f,%f,%f,%f]\n";
    float floatargs[9] = {1.1f,2.2f,3.3f,4.4f,5.5f,6.6f,7.7f,8.8f,9.9f};
    ffi_status status;
    int result;
    arg_types[0] = &ffi_type_pointer;
    for(i=1 ; i<10 ; i++)
    {
        arg_types[i] = &ffi_type_float;
    }
    if((status = ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 10,
                              &ffi_type_sint, arg_types)) != FFI_OK)
    {
        fprintf(stderr, "ffi_prep_cif_var() failed!\n");
        return;
    }
    arg_values[0] = &fmt;
    for(i=1 ; i<10 ; i++)
    {
        arg_values[i] = &floatargs[i-1];
    }
    printf("Non-variadic call:\n");
    ffi_call(&cif, FFI_FN(print9float), &result, arg_values);
    printf("result is %i\n", result);
}

void test_varfloat()
{
    size_t i;
    ffi_cif cif;
    ffi_type *arg_types[10];
    void     *arg_values[10];
    char *fmt = "[%f,%f,%f,%f,%f,%f,%f,%f,%f]\n";
    float floatargs[9] = {1.1f,2.2f,3.3f,4.4f,5.5f,6.6f,7.7f,8.8f,9.9f};
    ffi_status status;
    int result;
    arg_types[0] = &ffi_type_pointer;
    for(i=1 ; i<10 ; i++)
    {
        arg_types[i] = &ffi_type_float;
    }
    if((status = ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 10,
                                  &ffi_type_sint, arg_types)) != FFI_OK)
    {
        fprintf(stderr, "ffi_prep_cif_var() failed!\n");
        return;
    }
    arg_values[0] = &fmt;
    for(i=1 ; i<10 ; i++)
    {
        arg_values[i] = &floatargs[i-1];
    }
    printf("Variadic call:\n");
    ffi_call(&cif, FFI_FN(printf), &result, arg_values);
    printf("result is %i\n", result);
}

int main()
{
    test_float();
    test_varfloat();
    return 0;
}


             reply	other threads:[~2016-10-10  7:04 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-10-10  7:04 Damien Thébault [this message]
2016-10-10  7:17 ` Andrew Pinski
2016-10-10  7:27   ` Damien Thébault
2016-10-11 13:27     ` Richard Henderson
2016-10-11 19:12       ` Damien Thébault

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=20161010070352.GA11072@han \
    --to=damien@dtbo.net \
    --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).