Fix C++ __guard implementation for ARM. The standard C++ ABI that most platforms follow defines __guard to be 64 bits. The existing implementation of libxx_cxa_guard.cxx follows this. However, the 32-bit ARM C++ ABI defines it as 32 bits instead, and changes the meaning slightly so only the lowest bit is used. This matters because GCC creates guard symbols without regards to what libxx_cxa_guard.cxx says. So on ARM, gcc allocates 4 bytes, but __cxa_guard_release writes 8 bytes, zeroing out another unlucky variable nearby. Fix it by special-casing 32-bit ARM in libxx_cxa_guard.

This commit is contained in:
Jim Paris 2017-06-09 07:16:00 -06:00 committed by Gregory Nutt
parent bf6709b887
commit 18289e17ce

View File

@ -38,6 +38,7 @@
//***************************************************************************
#include <nuttx/compiler.h>
#include <cxxabi.h>
//***************************************************************************
// Pre-processor Definitions
@ -47,7 +48,20 @@
// Private Types
//***************************************************************************
#ifdef __ARM_EABI__
// The 32-bit ARM C++ ABI specifies that the guard is a 32-bit
// variable and the least significant bit contains 0 prior to
// initialization, and 1 after.
typedef int __guard;
#else
// The "standard" C++ ABI specifies that the guard is a 64-bit
// variable and the first byte contains 0 prior to initialization, and
// 1 after.
__extension__ typedef int __guard __attribute__((mode(__DI__)));
#endif
//***************************************************************************
// Private Data
@ -65,7 +79,11 @@ extern "C"
int __cxa_guard_acquire(FAR __guard *g)
{
return !*g;
#ifdef __ARM_EABI__
return !(*g & 1);
#else
return !*(char *)g;
#endif
}
//*************************************************************************
@ -74,7 +92,11 @@ extern "C"
void __cxa_guard_release(FAR __guard *g)
{
#ifdef __ARM_EABI__
*g = 1;
#else
*(char *)g = 1;
#endif
}
//*************************************************************************