[Vm-dev] [OpenSmalltalk/opensmalltalk-vm] passing struct by value does not respect x86_64 SysV ABI (#443)
Todd Blanchard
tblanchard at mac.com
Fri Nov 8 16:41:12 UTC 2019
I think I ran into this trying to build FFI to libclang.
It passes a lot of structs by value and some calls came back with nothing.
My message to vm-dev at lists.squeakfoundation.org on Nov 21, 2017 follows;
Apologies if this isn't relevant.
> I've been trying to track this down for a couple weeks now.
>
> I have concluded that structs passed by value to functions on the 64 bit VM are not properly populated. The struct's memory is all zero'd.
>
> I found this while trying to work with LibClang and found that functions that fetched code locations from code ranges always returned invalid zero'd locations. After spending some time with lldb I have traced the problem into the native code and found that the argument is not correct.
>
> I've carved out the wee bit of clang to reproduce this in a tiny library.
>
> The gist of it is below and the entire file is included. Basically the struct passed to the function clang_getRangeStart is zero'd memory regardless of the data I send from the image side.
>
> The build command I used on sierra is clang -shared -undefined dynamic_lookup -o microclang.dylib microclang.c
>
> I'm stuck. The FFI64 plugin is way beyond my comprehension.
>
> // microclang.c
>
> typedef struct {
> const void *ptr_data[2];
> unsigned int_data;
> } CXSourceLocation;
>
> /**
> * \brief Identifies a half-open character range in the source code.
> *
> * Use clang_getRangeStart() and clang_getRangeEnd() to retrieve the
> * starting and end locations from a source range, respectively.
> */
> typedef struct {
> const void *ptr_data[2];
> unsigned begin_int_data;
> unsigned end_int_data;
> } CXSourceRange;
>
> const char* first = "first_pointer";
> const char* second = "second_pointer";
>
> // return a fake range with non zero data
> CXSourceRange clang_getArbitraryRange()
> {
> CXSourceRange range = {0};
> range.ptr_data[0] = (void*)first;
> range.ptr_data[1] = (void*)second;
> range.begin_int_data = 17;
> range.end_int_data = 24;
> return range;
> }
>
> // Actual clang function - range is always zero'd here despite having values in the image
> CXSourceLocation clang_getRangeStart(CXSourceRange range) {
> // Special decoding for CXSourceLocations for CXLoadedDiagnostics.
> if ((uintptr_t)range.ptr_data[0] & 0x1) {
> CXSourceLocation Result = { { range.ptr_data[0], nullptr }, 0 };
> return Result;
> }
>
> CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] },
> range.begin_int_data };
> return Result;
> }
>
>
> On Nov 6, 2019, at 12:57 PM, Nicolas Cellier <notifications at github.com> wrote:
>
> For passing parameters by value, my understanding is that we can pass up to 8 eigthbytes individually for each struct (either via register if struct fits on two eightbytes, and if we still have available registers, or via stack...). Only for more than 8 eightbytes, we will pass by MEMORY (a pointer to struct).
>
> Here is a little example:
>
> double adi(sdi x) { return (double) x.a + (double) x.b ; }
> double adi_2(sdi x,sdi y) { return adi(x) + adi(y); }
> double adi_4(sdi x,sdi y,sdi z,sdi t) { return adi_2(x,y) + adi_2(z,t); }
>
> double aslf(sslf x) { return (double) x.a + (double) x.b + (double) x.c ; }
> double aslf_2(sslf x,sslf y) { return aslf(x) + aslf(y); }
> double aslf_4(sslf x,sslf y,sslf z,sslf t) { return aslf_2(x,y) + aslf_2(z,t); }
> double-int are passed by registers (by value) because fitting on 2 eightbytes
> short-long-float are passed via stack (by value) because requiring 3 eightbytes
> We should try longer (> 8 eightbytes) and verify that they are passed by pointer...
>
> —
> You are receiving this because you are subscribed to this thread.
> Reply to this email directly, view it on GitHub <https://github.com/OpenSmalltalk/opensmalltalk-vm/issues/443?email_source=notifications&email_token=AIJPEW3KXWHZHIYSFPN56DDQSMVU3A5CNFSM4JJ3EAU2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEDH6XYY#issuecomment-550497251>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/AIJPEW6526SF2E4V5NDITSTQSMVU3ANCNFSM4JJ3EAUQ>.
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20191108/fae15d19/attachment-0003.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: LibCClang-FFI-Binding.st
Type: application/octet-stream
Size: 5652 bytes
Desc: not available
URL: <http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20191108/fae15d19/attachment-0002.obj>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20191108/fae15d19/attachment-0004.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: microclang.c
Type: application/octet-stream
Size: 1760 bytes
Desc: not available
URL: <http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20191108/fae15d19/attachment-0003.obj>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20191108/fae15d19/attachment-0005.html>
More information about the Vm-dev
mailing list