Skip to content

Pass struct by value not passing copy on win64 #305

@embray

Description

@embray

Forgive me if this is already a known issue or if I'm missing something, though I couldn't find any obvious reference to it. I ran across this issue via running the test suite for Python on Cygwin 64-bit. The following simple example reproduces the problem:

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

typedef struct {
    unsigned long first;
    unsigned long second;
    unsigned long third;
} Test;


static void update_value(Test in) {
    ((volatile Test*)&in)->first = 0x0badf00d;
    ((volatile Test*)&in)->second = 0x0badf00d;
    ((volatile Test*)&in)->third = 0x0badf00d;
}


int main(void) {
    ffi_cif cif;
    ffi_type *args[1];
    void *values[1];
    ffi_type Test_type;
    ffi_type *Test_type_elements[4];
    int idx;

    Test test = {0xdeadbeef, 0xcafebabe, 0x0bad1dea};

    Test_type.size = Test_type.alignment = 0;
    Test_type.elements = (ffi_type **)&Test_type_elements;

    for (idx = 0; idx < 3; idx++) {
        Test_type_elements[idx] = &ffi_type_ulong;
    }
    Test_type_elements[3] = NULL;

    args[0] = &Test_type;
    values[0] = (void*)&test;

    if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ffi_type_void, args) == FFI_OK) {
        ffi_call(&cif, (void*)update_value, NULL, values);
        printf("test.first = 0x%08lx\n", test.first);
        assert(test.first == 0xdeadbeef);
    } else {
        printf("Error with ffi_prep_cif\n");
    }
    return 0;
}

Just looking at ffiw64.c I think it's pretty simplistic--it always just passes struct types by reference, and doesn't make a copy first before a pass by value.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions