Bug ID 33042
Summary Unable to read return value of arm64 functions returning large objects
Component All Bugs
Aarch64 Procedure Call Standard specifies that for returning large objects, the caller passes in a pointer in the x8 register, which points to the memory which will be populated by the result. However, it does not state that the function needs to preserve this register -- it remains a volatile reg, like the registers used to pass other arguments. Now, ABISysV_arm64 plugin implements "get the return value of a function call" functionality by reading the x8 register *after* the function returns, and decoding the memory it points to. This is wrong, as the register could be clobbered by that point. It happens to work for simple functions that don't do much, in most cases, but for example it fails if the compiler decides to copy the object into the destination via memcpy, and memcpy clobbers r8 (this happens with clang and some versions of android libc, at least). It's not really clear to me how this can be improved, but I'm filing this bug for posterity, and in case anyone has an idea. I guess it could be done if the caller specifies (via dwarf?) the memory it expects the result to be put in, but as far as I can tell, there is no such dwarf facility at the moment. In the mean time, I am going to disable the relevant checks in TestReturnValue for targets I know to be affected.