forked from OSchip/llvm-project
[libcxxabi] Add __cxa_thread_atexit for TLS support on Linux.
Summary: Fixes PR21738. The implementation for this is handled by __cxa_thread_atexit_impl, which is supplied by libc. More information: https://sourceware.org/glibc/wiki/Destructor%20support%20for%20thread_local%20variables Reviewers: mclow.lists, EricWF, jroelofs Reviewed By: jroelofs Subscribers: majnemer, cfe-commits Differential Revision: http://reviews.llvm.org/D6708 llvm-svn: 224477
This commit is contained in:
parent
8e015ff43b
commit
12c0c8b67f
|
@ -38,3 +38,5 @@ check_library_exists(c printf "" LIBCXXABI_HAS_C_LIB)
|
|||
check_library_exists(dl dladdr "" LIBCXXABI_HAS_DL_LIB)
|
||||
check_library_exists(pthread pthread_once "" LIBCXXABI_HAS_PTHREAD_LIB)
|
||||
check_library_exists(gcc_eh _Unwind_GetRegionStart "" LIBCXXABI_HAS_GCC_EH_LIB)
|
||||
check_library_exists(c __cxa_thread_atexit_impl ""
|
||||
LIBCXXABI_HAS_CXA_THREAD_ATEXIT_IMPL)
|
||||
|
|
|
@ -178,6 +178,12 @@ extern void __cxa_decrement_exception_refcount(void* primary_exception) throw();
|
|||
// Apple addition to support std::uncaught_exception()
|
||||
extern bool __cxa_uncaught_exception() throw();
|
||||
|
||||
#ifdef __linux__
|
||||
// Linux TLS support. Not yet an official part of the Itanium ABI.
|
||||
// https://sourceware.org/glibc/wiki/Destructor%20support%20for%20thread_local%20variables
|
||||
extern int __cxa_thread_atexit(void (*)(void *), void *, void *) throw();
|
||||
#endif
|
||||
|
||||
} // extern "C"
|
||||
} // namespace __cxxabiv1
|
||||
|
||||
|
|
|
@ -19,6 +19,10 @@ set(LIBCXXABI_SOURCES
|
|||
typeinfo.cpp
|
||||
)
|
||||
|
||||
if (UNIX AND NOT (APPLE OR CYGWIN))
|
||||
list(APPEND LIBCXXABI_SOURCES cxa_thread_atexit.cpp)
|
||||
endif()
|
||||
|
||||
set(LIBCXXABI_HEADERS ../include/cxxabi.h)
|
||||
|
||||
# Add all the headers to the project for IDEs.
|
||||
|
@ -44,6 +48,10 @@ endif()
|
|||
|
||||
include_directories("${LIBCXXABI_LIBCXX_INCLUDES}")
|
||||
|
||||
if (LIBCXXABI_HAS_CXA_THREAD_ATEXIT_IMPL)
|
||||
add_definitions(-DHAVE___CXA_THREAD_ATEXIT_IMPL)
|
||||
endif()
|
||||
|
||||
# Generate library list.
|
||||
set(libraries ${LIBCXXABI_CXX_ABI_LIBRARIES})
|
||||
append_if(libraries LIBCXXABI_HAS_C_LIB c)
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
//===----------------------- cxa_thread_atexit.cpp ------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "cxxabi.h"
|
||||
|
||||
namespace __cxxabiv1 {
|
||||
|
||||
extern "C" {
|
||||
|
||||
#ifdef HAVE___CXA_THREAD_ATEXIT_IMPL
|
||||
|
||||
int __cxa_thread_atexit(void (*dtor)(void *), void *obj,
|
||||
void *dso_symbol) throw() {
|
||||
extern int __cxa_thread_atexit_impl(void (*)(void *), void *, void *);
|
||||
return __cxa_thread_atexit_impl(dtor, obj, dso_symbol);
|
||||
}
|
||||
|
||||
#endif // HAVE__CXA_THREAD_ATEXIT_IMPL
|
||||
|
||||
} // extern "C"
|
||||
|
||||
} // namespace __cxxabiv1
|
|
@ -0,0 +1,33 @@
|
|||
//===--------------------- cxa_thread_atexit_test.cpp ---------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// REQUIRES: linux2
|
||||
|
||||
#include <assert.h>
|
||||
#include <cxxabi.h>
|
||||
|
||||
static bool AtexitImplCalled = false;
|
||||
|
||||
extern "C" int __cxa_thread_atexit_impl(void (*dtor)(void *), void *obj,
|
||||
void *dso_symbol) {
|
||||
assert(dtor == reinterpret_cast<void (*)(void *)>(1));
|
||||
assert(obj == reinterpret_cast<void *>(2));
|
||||
assert(dso_symbol == reinterpret_cast<void *>(3));
|
||||
AtexitImplCalled = true;
|
||||
return 4;
|
||||
}
|
||||
|
||||
int main() {
|
||||
int RV = __cxxabiv1::__cxa_thread_atexit(
|
||||
reinterpret_cast<void (*)(void *)>(1), reinterpret_cast<void *>(2),
|
||||
reinterpret_cast<void *>(3));
|
||||
assert(RV = 4);
|
||||
assert(AtexitImplCalled);
|
||||
return 0;
|
||||
}
|
|
@ -283,6 +283,8 @@ elif sys.platform.startswith('linux'):
|
|||
else:
|
||||
lit_config.fatal("unrecognized system")
|
||||
|
||||
config.available_features.add(sys.platform)
|
||||
|
||||
config.test_format = LibcxxabiTestFormat(
|
||||
cxx_under_test,
|
||||
cpp_flags = ['-nostdinc++'] + compile_flags + include_paths,
|
||||
|
|
Loading…
Reference in New Issue