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@0.0 "
returns 0.0@0.0 instead of 3.0@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 ... ".
[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."