[llvm-dev] compler-rt, __aeabi_memcpy () possibly broken (ARM)
Peter Jakubek via llvm-dev
llvm-dev at lists.llvm.org
Sun Apr 10 12:37:22 PDT 2016
I recognized that compiler-rt's the implementation of __aeabi_memcpy
simply branches to memcpy.
The implementation of memcpy is not provided. So an externally provided
memcpy () has to be used.
(also applies to memmove, memset, memclr)
On ARM I have seen implementations of memcpy () using floating-point
registers (if compiled with NEON support). The is perfectly
legal, as memcpy () only needs to comply with the Procedure Call
Standard. According to this d0-d7, d16-d31 are scratch registers.
The situation is slightly different for __aeabi_memcpy (). The ABI spec
explicitly states: "In general, implementations of these
functions are allowed to corrupt only the integer core registers
permitted to be corrupted by the [AAPCS] (r0-r3, ip, lr, and CPSR)."
newlib addresses this by explicitly providing a separate implementation
for __aeabi_memcpy () and memcpy ().
But things can get messed up if compiler-rt's __aeabi_memcpy () is
actually used. (with any memcpy () that clobbers flating-point
The implementation of __aeabi_memcpy () in ARM's compiler 5 tool-chain
also uses floating-point registers - but preserves the contents.
So this one is ABI compliant.
My conclusion is that the current implementation of compiler-rt can
potentially introduce difficult to track down problems.
Unless of course LLVM always can handle corrupted floating-point
registers for all calls to __aeabi_memcpy ().
Either the aeabi variants of memcpy, memmove, memset, memclr should be
fixed or the stubs should removed from compiler-rt.
Or am I getting it all wrong?
More information about the llvm-dev