[squeak-dev] Alien primFFICall returning struct with 64bit vm

Nicolas Cellier nicolas.cellier.aka.nice at gmail.com
Wed Nov 6 19:14:55 UTC 2019


I have opened https://github.com/OpenSmalltalk/opensmalltalk-vm/issues/443
because it won't be solved that easily... It might take some time.

Le mer. 6 nov. 2019 à 14:16, Nicolas Cellier <
nicolas.cellier.aka.nice at gmail.com> a écrit :

> Wikipedia tells that ou assumptions are wrong:
>
> https://en.wikipedia.org/wiki/X86_calling_conventions
>
> or if you prefer going to the reference:
>
> https://github.com/hjl-tools/x86-psABI/wiki/x86-64-psABI-1.0.pdf
>
> You'll see that the rules are quite complex!
> Notably, page 21, the structure has class MEMORY if longer than eight
> eightbyte (that's 64 bytes !).
> So you should open bug report on Smalltalk side...
> And we lack many tests...
>
> Le mer. 6 nov. 2019 à 13:56, Nicolas Cellier <
> nicolas.cellier.aka.nice at gmail.com> a écrit :
>
>>  Hi Balazs,
>> I confirm what you observe.
>> If I compile the source with:
>>
>>     clang --shared -o libalientest.so -Os alientest.c
>>
>> then disassemble with:
>>
>>     objdump -D libalientest.so  | less
>>
>> I get this:
>>
>>     000000000000057c <atv>:
>>      57c:   c3                      retq
>>
>>     000000000000057d <at34>:
>>      57d:   f2 0f 10 05 1b 00 00    movsd  0x1b(%rip),%xmm0        # 5a0
>> <_fini+0x10>
>>      584:   00
>>      585:   f2 0f 10 0d 1b 00 00    movsd  0x1b(%rip),%xmm1        # 5a8
>> <_fini+0x18>
>>      58c:   00
>>      58d:   c3                      retq
>>
>> Code is highly suspicious for atv...
>> at34 just load the constants in dregs, then do nothing (inline atv).
>> So this does not work as advertized...
>>
>> The non optimized version is very convoluted:
>>
>> 0000000000000580 <atv>:
>>  580:   55                      push   %rbp
>>  581:   48 89 e5                mov    %rsp,%rbp
>>  584:   f2 0f 11 45 e8          movsd  %xmm0,-0x18(%rbp)
>>  589:   f2 0f 11 4d e0          movsd  %xmm1,-0x20(%rbp)
>>  58e:   f2 0f 10 45 e8          movsd  -0x18(%rbp),%xmm0
>>  593:   f2 0f 11 45 d0          movsd  %xmm0,-0x30(%rbp)
>>  598:   f2 0f 10 45 e0          movsd  -0x20(%rbp),%xmm0
>>  59d:   f2 0f 11 45 d8          movsd  %xmm0,-0x28(%rbp)
>>  5a2:   0f 10 45 d0             movups -0x30(%rbp),%xmm0
>>  5a6:   0f 29 45 f0             movaps %xmm0,-0x10(%rbp)
>>  5aa:   f2 0f 10 45 f0          movsd  -0x10(%rbp),%xmm0
>>  5af:   f2 0f 10 4d f8          movsd  -0x8(%rbp),%xmm1
>>  5b4:   5d                      pop    %rbp
>>  5b5:   c3                      retq
>>  5b6:   66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
>>  5bd:   00 00 00
>>
>> 00000000000005c0 <at34>:
>>  5c0:   55                      push   %rbp
>>  5c1:   48 89 e5                mov    %rsp,%rbp
>>  5c4:   48 83 ec 10             sub    $0x10,%rsp
>>  5c8:   f2 0f 10 05 38 00 00    movsd  0x38(%rip),%xmm0        # 608
>> <_fini+0x10>
>>  5cf:   00
>>  5d0:   f2 0f 10 0d 38 00 00    movsd  0x38(%rip),%xmm1        # 610
>> <_fini+0x18>
>>  5d7:   00
>>  5d8:   e8 a3 ff ff ff          callq  580 <atv>
>>  5dd:   f2 0f 11 45 f0          movsd  %xmm0,-0x10(%rbp)
>>  5e2:   f2 0f 11 4d f8          movsd  %xmm1,-0x8(%rbp)
>>  5e7:   f2 0f 10 45 f0          movsd  -0x10(%rbp),%xmm0
>>  5ec:   f2 0f 10 4d f8          movsd  -0x8(%rbp),%xmm1
>>  5f1:   48 83 c4 10             add    $0x10,%rsp
>>  5f5:   5d                      pop    %rbp
>>  5f6:   c3                      retq
>>
>> It's clear that the resulting structure is passed via first 2 dregs (xmm0
>> and xmm1).
>> Doesn't it qualify as a clang bug? Or is our interpretation of ABI
>> erroneous?
>> I would opt for the later...
>>
>> Le mar. 5 nov. 2019 à 23:54, Balázs Kósi <rebmekop at gmail.com> a écrit :
>>
>>> Hi all,
>>>
>>> I'm having trouble with calling struct returning functions with alien on
>>> a 64bit linux vm using the hidden first argument mechanism [1]. The
>>> function gets called, but the result is not copied into the struct pointed
>>> by the hidden argument.
>>>
>>> I tried to debug what happens with gdb, but everything looks fine,
>>> except not getting the result back. The address is copied into %rdi
>>> (regs[0]) in dax64business.h:92 [2], which is exactly what the spec says
>>> [3].
>>>
>>> Here is a minimal example calling a C function returning a struct with
>>> two doubles:
>>>
>>> at34 := Alien lookup: 'at34' inLibrary: 'libalientest.so'.
>>> at34 primFFICallResult: nil with: (r := Alien newC: 16) pointer.
>>> vec := (r doubleAt: 1) @ (r doubleAt: 9). r free. vec " 0.0 at 0.0 "
>>>
>>> returns 0.0 at 0.0 instead of 3.0 at 4.0
>>>
>>> the C code goes like this:
>>>
>>> typedef struct atvect{double x, y;} atvect;
>>>
>>> atvect atv(double x, double y) {
>>>   atvect v = {x, y};
>>>   return v;
>>> }
>>>
>>> atvect at34() {
>>>   return atv(3.0, 4.0);
>>> }
>>>
>>> The vm is sqcogspur64linuxht 5.0-201910291408. The image is a recent
>>> trunk image (update: #19142), image format 68021 (64 bit). Alien is
>>> Alien-Core-TorstenBergmann.101.mcz.
>>>
>>> What am I missing?
>>>
>>> Thanks, Balázs
>>>
>>> [1] "The rules for structure results vary slightly by platform. Most
>>> functions returning structures expect a “hidden” first parameter holding
>>> the result struct’s address. Because the FFI provides no abstraction one
>>> must pass this parameter explicitly. ... On linux all struct results are
>>> re-turned through the hidden first argument mechanism ... ".
>>>
>>> https://wiki.squeak.org/squeak/uploads/6100/Alien%20FFI.2.pdf
>>>
>>> [2]
>>> https://github.com/OpenSmalltalk/opensmalltalk-vm/blob/a8a1dc1e33267e0fa2dab22959e41d0a072420d9/platforms/Cross/plugins/IA32ABI/dax64business.h#L92
>>>
>>> [3] "2. If the type has class MEMORY, then the caller provides space for
>>> the return value and passes the address of this storage in %rdi as if it
>>> were the first
>>> argument to the function. In effect, this address becomes a “hidden”
>>> first ar-
>>> gument. This storage must not overlap any data visible to the callee
>>> through
>>> other names than this argument.
>>> On return %rax will contain the address that has been passed in by the
>>> caller in %rdi."
>>>
>>> https://github.com/hjl-tools/x86-psABI/wiki/x86-64-psABI-1.0.pdf p.24.
>>>
>>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20191106/e6a8f1d1/attachment.html>


More information about the Squeak-dev mailing list