[Vm-dev] FFI Struct Argument Pass By Value Fails on Mac 64 bit
Todd Blanchard
tblanchard at mac.com
Wed Nov 22 06:23:08 UTC 2017
Playground code:
LibCClang startFromRange:(LibCClang defaultRange)
it worked if the resulting struct is not all zeroes.
A tiny C program is the equivalent.
int main()
{
if(clang_getRangeStart(clang_getArbitraryRange()).begin_int_data == 0) printf("That failed\n");
else printf("That worked\n")
return 0;
}
> On Nov 21, 2017, at 11:18 PM, Ben Coman <btc at openinworld.com> wrote:
>
> Hi Todd,
>
> Could you advise the the Playground code to use to test this?
> And maybe a C program that links to the microclang shared library that does the equivalent test?
>
> cheers -ben
>
> On 22 November 2017 at 13:38, Todd Blanchard <tblanchard at mac.com <mailto:tblanchard at mac.com>> wrote:
>
> 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;
> }
>
>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20171121/6861ce71/attachment.html>
More information about the Vm-dev
mailing list