[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 mailing list