scudo: Only use the Android reserved TLS slot when building libc's copy of the allocator.

When we're not building libc's allocator, just use a regular TLS variable. This
lets the unit tests pass on Android devices whose libc uses Scudo. Otherwise
libc's copy of Scudo and the unit tests' copy will both try to use the same
TLS slot, in likely incompatible ways.

This requires using ELF TLS, so start passing -fno-emulated-tls when building
the library and the unit tests on Android.

Differential Revision: https://reviews.llvm.org/D70472
This commit is contained in:
Peter Collingbourne 2019-11-19 13:58:06 -08:00
parent a9bb669e59
commit f751a79173
3 changed files with 10 additions and 4 deletions

View File

@ -29,6 +29,8 @@ list(APPEND SCUDO_LINK_FLAGS -Wl,-z,defs,-z,now,-z,relro)
append_list_if(COMPILER_RT_HAS_NODEFAULTLIBS_FLAG -nodefaultlibs SCUDO_LINK_FLAGS)
if(ANDROID)
list(APPEND SCUDO_CFLAGS -fno-emulated-tls)
# Put the shared library in the global group. For more details, see
# android-changes-for-ndk-developers.md#changes-to-library-search-order
append_list_if(COMPILER_RT_HAS_Z_GLOBAL -Wl,-z,global SCUDO_LINK_FLAGS)

View File

@ -16,6 +16,10 @@ set(SCUDO_UNITTEST_CFLAGS
# TODO(kostyak): find a way to make -fsized-deallocation work
-Wno-mismatched-new-delete)
if(ANDROID)
list(APPEND SCUDO_UNITTEST_CFLAGS -fno-emulated-tls)
endif()
set(SCUDO_TEST_ARCH ${SCUDO_STANDALONE_SUPPORTED_ARCH})
# gtests requires c++

View File

@ -72,7 +72,7 @@ template <class Allocator, u32 MaxTSDCount> struct TSDRegistrySharedT {
private:
ALWAYS_INLINE void setCurrentTSD(TSD<Allocator> *CurrentTSD) {
#if SCUDO_ANDROID
#if _BIONIC
*getAndroidTlsPtr() = reinterpret_cast<uptr>(CurrentTSD);
#elif SCUDO_LINUX
ThreadTSD = CurrentTSD;
@ -84,7 +84,7 @@ private:
}
ALWAYS_INLINE TSD<Allocator> *getCurrentTSD() {
#if SCUDO_ANDROID
#if _BIONIC
return reinterpret_cast<TSD<Allocator> *>(*getAndroidTlsPtr());
#elif SCUDO_LINUX
return ThreadTSD;
@ -152,12 +152,12 @@ private:
u32 CoPrimes[MaxTSDCount];
bool Initialized;
HybridMutex Mutex;
#if SCUDO_LINUX && !SCUDO_ANDROID
#if SCUDO_LINUX && !_BIONIC
static THREADLOCAL TSD<Allocator> *ThreadTSD;
#endif
};
#if SCUDO_LINUX && !SCUDO_ANDROID
#if SCUDO_LINUX && !_BIONIC
template <class Allocator, u32 MaxTSDCount>
THREADLOCAL TSD<Allocator>
*TSDRegistrySharedT<Allocator, MaxTSDCount>::ThreadTSD;