public inbox for libffi-discuss@sourceware.org
 help / color / mirror / Atom feed
* pass by value and also snprintf()
@ 2015-04-27 16:59 Bruce Korb
  2015-04-27 17:09 ` Richard Henderson
  0 siblings, 1 reply; 7+ messages in thread
From: Bruce Korb @ 2015-04-27 16:59 UTC (permalink / raw)
  To: libffi-discuss

I read this paragraph and have a question:

  avalues is a vector of void * pointers that point to the memory
locations holding the argument values for a call.
  If cif declares that the function has no arguments (i.e., nargs was
0), then avalues is ignored. Note that
  argument values may be modified by the callee (for instance, structs
passed by value); the burden of
  copying pass-by-value arguments is placed on the caller.

If libffi moves the values into places where the callee can find them,
it would be interesting
to know how the callee can modify the original value.  That value
cannot be at the place pointed to
by the "avalues" array of pointers.

- - - - -

Anyway, I believe in my last missive, I had all the arguments for
snprintf() set up correctly,
yet snprintf faulted anyway.  Since GDB showed everything as I would
expect and since
I cannot make much sense of what the ffi_call_unix64 is doing, I hope
there is an
obvious answer to what I am missing:

https://sourceware.org/ml/libffi-discuss/2015/msg00063.html

Thank you in advance!  Regards, Bruce

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: pass by value and also snprintf()
  2015-04-27 16:59 pass by value and also snprintf() Bruce Korb
@ 2015-04-27 17:09 ` Richard Henderson
  2015-04-27 17:37   ` Bruce Korb
  0 siblings, 1 reply; 7+ messages in thread
From: Richard Henderson @ 2015-04-27 17:09 UTC (permalink / raw)
  To: Bruce Korb, libffi-discuss

On 04/27/2015 09:59 AM, Bruce Korb wrote:
> I hope
> there is an
> obvious answer to what I am missing:

Certainly there's no way we can help you further without a complete test case.


r~

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: pass by value and also snprintf()
  2015-04-27 17:09 ` Richard Henderson
@ 2015-04-27 17:37   ` Bruce Korb
  2015-04-27 17:45     ` Bruce Korb
  2015-04-27 18:02     ` Richard Henderson
  0 siblings, 2 replies; 7+ messages in thread
From: Bruce Korb @ 2015-04-27 17:37 UTC (permalink / raw)
  To: Richard Henderson; +Cc: libffi-discuss

Like this then:


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

#define UCONST(_p)  ((void *)(uintptr_t)_p)

int
main(int argc, char ** argv)
{
        char       buffer[0x1000];
        size_t     bufsz  = sizeof(buffer);
        char const fmt[]  = "Allocated sblock_id=%d for band_id=%d\n";
        int32_t    sblock = 1;
        int32_t    band   = 1;
        void *     fn     = sprintf;

        if (sizeof(bufsz) != sizeof(uint64_t))
                return 1;

        ffi_type * typ[5] = {
                [0] = &ffi_type_pointer,
                [1] = &ffi_type_uint64,
                [2] = &ffi_type_pointer,
                [3] = &ffi_type_sint32,
                [4] = &ffi_type_sint32 };

        void * values[5] = {
                [0] = buffer,
                [1] = &bufsz,
                [2] = UCONST(fmt),
                [3] = &sblock,
                [4] = &band };

        ffi_cif cif;

        if (ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 3, 5,
&ffi_type_uint32, typ) == FFI_OK) {
uint32_t ret_val;

ffi_call(&cif, fn, &ret_val, values);
                fputs(buffer, stdout);
                return 0;
        }
        return 1;
}

$ cc -o ffi-test ffi-test.c -lffi
$ ./ffi-test
Segmentation fault

On Mon, Apr 27, 2015 at 10:09 AM, Richard Henderson <rth@redhat.com> wrote:
> On 04/27/2015 09:59 AM, Bruce Korb wrote:
>> I hope
>> there is an
>> obvious answer to what I am missing:
>
> Certainly there's no way we can help you further without a complete test case.
>
>
> r~

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: pass by value and also snprintf()
  2015-04-27 17:37   ` Bruce Korb
@ 2015-04-27 17:45     ` Bruce Korb
  2015-04-27 17:48       ` Bruce Korb
  2015-04-27 18:02     ` Richard Henderson
  1 sibling, 1 reply; 7+ messages in thread
From: Bruce Korb @ 2015-04-27 17:45 UTC (permalink / raw)
  To: Richard Henderson; +Cc: libffi-discuss

s/sprintf/snprintf/  -- I had it right in the original code, and with
that fix it still seg faults.

On Mon, Apr 27, 2015 at 10:37 AM, Bruce Korb <bruce.korb@gmail.com> wrote:
> Like this then:
>
>
> #include <stdint.h>
> #include <stdio.h>
> #include <ffi.h>
>
> #define UCONST(_p)  ((void *)(uintptr_t)_p)
>
> int
> main(int argc, char ** argv)
> {
>         char       buffer[0x1000];
>         size_t     bufsz  = sizeof(buffer);
>         char const fmt[]  = "Allocated sblock_id=%d for band_id=%d\n";
>         int32_t    sblock = 1;
>         int32_t    band   = 1;
>         void *     fn     = sprintf;
>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: pass by value and also snprintf()
  2015-04-27 17:45     ` Bruce Korb
@ 2015-04-27 17:48       ` Bruce Korb
  0 siblings, 0 replies; 7+ messages in thread
From: Bruce Korb @ 2015-04-27 17:48 UTC (permalink / raw)
  To: Richard Henderson; +Cc: libffi-discuss

The GDB result (using snprintf this time):

(gdb)
37              if (ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 3, 5,
(gdb)
41                      ffi_call(&cif, fn, &ret_val, values);
(gdb)

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff787f562 in vsnprintf () from /lib/x86_64-linux-gnu/libc.so.6
(gdb) bt
#0  0x00007ffff787f562 in vsnprintf () from /lib/x86_64-linux-gnu/libc.so.6
#1  0x00007ffff7861532 in snprintf () from /lib/x86_64-linux-gnu/libc.so.6
#2  0x00007ffff7bd7adc in ffi_call_unix64 () from
/usr/lib/x86_64-linux-gnu/libffi.so.6
#3  0x00007ffff7bd740c in ffi_call () from /usr/lib/x86_64-linux-gnu/libffi.so.6
#4  0x0000000000400ac0 in main (argc=1, argv=0x7fffffffe488) at ffi-test.c:41


If I link against the -O0 -ggdb3 version of libffi, what can I do to
help diagnose?

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: pass by value and also snprintf()
  2015-04-27 17:37   ` Bruce Korb
  2015-04-27 17:45     ` Bruce Korb
@ 2015-04-27 18:02     ` Richard Henderson
  2015-04-27 18:54       ` Bruce Korb
  1 sibling, 1 reply; 7+ messages in thread
From: Richard Henderson @ 2015-04-27 18:02 UTC (permalink / raw)
  To: Bruce Korb; +Cc: libffi-discuss

On 04/27/2015 10:37 AM, Bruce Korb wrote:
> int
> main(int argc, char ** argv)
> {
>         char       buffer[0x1000];
>         size_t     bufsz  = sizeof(buffer);
>         char const fmt[]  = "Allocated sblock_id=%d for band_id=%d\n";
>         int32_t    sblock = 1;
>         int32_t    band   = 1;
>         void *     fn     = sprintf;
...
>         void * values[5] = {
>                 [0] = buffer,
>                 [1] = &bufsz,
>                 [2] = UCONST(fmt),
>                 [3] = &sblock,
>                 [4] = &band };

That would be because you're passing buffer and fmt instead of a pointer to
buffer and fmt.  You need to do

        char *     buffer_p = buffer;
        const char *fmt_p = fmt;

        void * values[5] = {
                [0] = &buffer_p,
                [1] = &bufsz,
                [2] = &fmt_p,
                [3] = &sblock,
                [4] = &band };

One of the many peculiarities of the libffi api...


r~

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: pass by value and also snprintf()
  2015-04-27 18:02     ` Richard Henderson
@ 2015-04-27 18:54       ` Bruce Korb
  0 siblings, 0 replies; 7+ messages in thread
From: Bruce Korb @ 2015-04-27 18:54 UTC (permalink / raw)
  To: Richard Henderson; +Cc: libffi-discuss

Hi Richard,  THANK YOU!!

> That would be because you're passing buffer and fmt instead of a pointer to
> buffer and fmt.  You need to do
>
>         char *     buffer_p = buffer;
>         const char *fmt_p = fmt;
>
>         void * values[5] = {
>                 [0] = &buffer_p,
>                 [1] = &bufsz,
>                 [2] = &fmt_p,
>                 [3] = &sblock,
>                 [4] = &band };
>
> One of the many peculiarities of the libffi api...

Indeed.  Worthy of a BOLD caveat in the docs.
Googling seems to point mostly here:
http://www.atmark-techno.com/~yashi/libffi.html
but it looks like my info doc, so I hope it is up to date.  Anyway, it was there
where I also saw that funny comment about altering passed values.
Based on my understanding of C and calling conventions, it seems pretty
impossible for a callee to alter a caller's value when passed by value, even if
one goes through libffi, so what is that comment trying to say?  (RE:
ffi_call())

Anyway, again, thank you!  Regards, Bruce

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2015-04-27 18:54 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-04-27 16:59 pass by value and also snprintf() Bruce Korb
2015-04-27 17:09 ` Richard Henderson
2015-04-27 17:37   ` Bruce Korb
2015-04-27 17:45     ` Bruce Korb
2015-04-27 17:48       ` Bruce Korb
2015-04-27 18:02     ` Richard Henderson
2015-04-27 18:54       ` Bruce Korb

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).