I have usercall
with calling convention I do not fully understand, it returns std::string
but IDA recognize it as void
.
I've noticed that every calle reads from x8/w8
afterwards, from wikipedia;
x8: used to hold indirect return value address
Can someone explain "indirect return value address" ?
From https://docs.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions?view=vs-2019
Return values
Integral values are returned in x0.
Floating-point values are returned in s0, d0, or v0, as appropriate.
HFA and HVA values are returned in s0-s3, d0-d3, or v0-v3, as appropriate.
Types returned by value are handled differently depending on whether they have certain properties. Types which have all of these properties,
they're aggregate by the C++14 standard definition, that is, they have no user-provided constructors, no private or protected non-static data members, no base classes, and no virtual functions, and they have a trivial copy-assignment operator, and they have a trivial destructor, use the following return style:
Types less than or equal to 8 bytes are returned in x0. Types less than or equal to 16 bytes are returned in x0 and x1, with x0 containing the lower-order 8 bytes.
For types greater than 16 bytes, the caller shall reserve a block of memory of sufficient size and alignment to hold the result. The address of the memory block shall be passed as an additional argument to the function in x8. The callee may modify the result memory block at any point during the execution of the subroutine. The callee isn't required to preserve the value stored in x8.
All other types use this convention:
The caller shall reserve a block of memory of sufficient size and alignment to hold the result. The address of the memory block shall be passed as an additional argument to the function in x0, or x1 if $this is passed in x0. The callee may modify the result memory block at any point during the execution of the subroutine. The callee returns the address of the memory block in x0.
Update 2:
From ARM docs
Registers with a special purpose
• X8 is the indirect result register. This is used to pass the address location of an indirect result, for example, where a function returns a large structure. ...
... the structure contains more than 16 bytes. According to the AAPCS for AArch64, the returned object is written to the memory pointed to by XR.