[Pharo-dev] FFI Struct Argument Pass By Value Fails on Mac 64 bit

Todd Blanchard tblanchard at mac.com
Wed Nov 22 00:38:05 EST 2017


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.pharo.org/pipermail/pharo-dev_lists.pharo.org/attachments/20171121/8843392e/attachment-0006.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.pharo.org/pipermail/pharo-dev_lists.pharo.org/attachments/20171121/8843392e/attachment.st>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.pharo.org/pipermail/pharo-dev_lists.pharo.org/attachments/20171121/8843392e/attachment-0007.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.pharo.org/pipermail/pharo-dev_lists.pharo.org/attachments/20171121/8843392e/attachment.c>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.pharo.org/pipermail/pharo-dev_lists.pharo.org/attachments/20171121/8843392e/attachment-0008.html>


More information about the Pharo-dev mailing list