[compiler-rt] r252738 - Implement some TLS support for PowerPC64.
Jay Foad via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 11 07:37:47 PST 2015
Author: foad
Date: Wed Nov 11 09:37:47 2015
New Revision: 252738
URL: http://llvm.org/viewvc/llvm-project?rev=252738&view=rev
Log:
Implement some TLS support for PowerPC64.
Summary: This is enough to get the asan static_tls.cc test case working.
Reviewers: eugenis, samsonov
Subscribers: llvm-commits
Differential Revision: http://reviews.llvm.org/D14574
Modified:
compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux_libcdep.cc
compiler-rt/trunk/lib/sanitizer_common/sanitizer_tls_get_addr.cc
compiler-rt/trunk/test/asan/TestCases/Linux/static_tls.cc
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux_libcdep.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux_libcdep.cc?rev=252738&r1=252737&r2=252738&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux_libcdep.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux_libcdep.cc Wed Nov 11 09:37:47 2015
@@ -166,11 +166,15 @@ static uptr g_tls_size;
# define DL_INTERNAL_FUNCTION
#endif
-#if defined(__mips__)
+#if defined(__mips__) || defined(__powerpc64__)
// TlsPreTcbSize includes size of struct pthread_descr and size of tcb
// head structure. It lies before the static tls blocks.
static uptr TlsPreTcbSize() {
- const uptr kTcbHead = 16;
+# if defined(__mips__)
+ const uptr kTcbHead = 16; // sizeof (tcbhead_t)
+# elif defined(__powerpc64__)
+ const uptr kTcbHead = 88; // sizeof (tcbhead_t)
+# endif
const uptr kTlsAlign = 16;
const uptr kTlsPreTcbSize =
(ThreadDescriptorSize() + kTcbHead + kTlsAlign - 1) & ~(kTlsAlign - 1);
@@ -201,9 +205,9 @@ void InitTlsSize() {
}
#if (defined(__x86_64__) || defined(__i386__) || defined(__mips__) \
- || defined(__aarch64__)) \
+ || defined(__aarch64__) || defined(__powerpc64__)) \
&& SANITIZER_LINUX && !SANITIZER_ANDROID
-// sizeof(struct thread) from glibc.
+// sizeof(struct pthread) from glibc.
static atomic_uintptr_t kThreadDescriptorSize;
uptr ThreadDescriptorSize() {
@@ -218,7 +222,7 @@ uptr ThreadDescriptorSize() {
char *end;
int minor = internal_simple_strtoll(buf + 8, &end, 10);
if (end != buf + 8 && (*end == '\0' || *end == '.')) {
- /* sizeof(struct thread) values from various glibc versions. */
+ /* sizeof(struct pthread) values from various glibc versions. */
if (SANITIZER_X32)
val = 1728; // Assume only one particular version for x32.
else if (minor <= 3)
@@ -254,6 +258,10 @@ uptr ThreadDescriptorSize() {
val = 1776;
atomic_store(&kThreadDescriptorSize, val, memory_order_relaxed);
return val;
+#elif defined(__powerpc64__)
+ val = 1776; // from glibc.ppc64le 2.20-8.fc21
+ atomic_store(&kThreadDescriptorSize, val, memory_order_relaxed);
+ return val;
#endif
return 0;
}
@@ -285,6 +293,15 @@ uptr ThreadSelf() {
descr_addr = thread_pointer - kTlsTcbOffset - TlsPreTcbSize();
# elif defined(__aarch64__)
descr_addr = reinterpret_cast<uptr>(__builtin_thread_pointer());
+# elif defined(__powerpc64__)
+ // PPC64LE uses TLS variant I. The thread pointer (in GPR 13)
+ // points to the end of the TCB + 0x7000. The pthread_descr structure is
+ // immediately in front of the TCB. TlsPreTcbSize() includes the size of the
+ // TCB and the size of pthread_descr.
+ const uptr kTlsTcbOffset = 0x7000;
+ uptr thread_pointer;
+ asm("addi %0,13,%1" : "=r"(thread_pointer) : "I"(-kTlsTcbOffset));
+ descr_addr = thread_pointer - TlsPreTcbSize();
# else
# error "unsupported CPU arch"
# endif
@@ -320,7 +337,7 @@ static void GetTls(uptr *addr, uptr *siz
*size = GetTlsSize();
*addr -= *size;
*addr += ThreadDescriptorSize();
-# elif defined(__mips__) || defined(__aarch64__)
+# elif defined(__mips__) || defined(__aarch64__) || defined(__powerpc64__)
*addr = ThreadSelf();
*size = GetTlsSize();
# else
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_tls_get_addr.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_tls_get_addr.cc?rev=252738&r1=252737&r2=252738&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_tls_get_addr.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_tls_get_addr.cc Wed Nov 11 09:37:47 2015
@@ -78,6 +78,15 @@ void DTLS_Destroy() {
DTLS_Deallocate(dtls.dtv, s);
}
+#if defined(__powerpc64__)
+// This is glibc's TLS_DTV_OFFSET:
+// "Dynamic thread vector pointers point 0x8000 past the start of each
+// TLS block."
+static const uptr kDtvOffset = 0x8000;
+#else
+static const uptr kDtvOffset = 0;
+#endif
+
DTLS::DTV *DTLS_on_tls_get_addr(void *arg_void, void *res,
uptr static_tls_begin, uptr static_tls_end) {
if (!common_flags()->intercept_tls_get_addr) return 0;
@@ -87,7 +96,7 @@ DTLS::DTV *DTLS_on_tls_get_addr(void *ar
DTLS_Resize(dso_id + 1);
if (dtls.dtv[dso_id].beg) return 0;
uptr tls_size = 0;
- uptr tls_beg = reinterpret_cast<uptr>(res) - arg->offset;
+ uptr tls_beg = reinterpret_cast<uptr>(res) - arg->offset - kDtvOffset;
VPrintf(2, "__tls_get_addr: %p {%p,%p} => %p; tls_beg: %p; sp: %p "
"num_live_dtls %zd\n",
arg, arg->dso_id, arg->offset, res, tls_beg, &tls_beg,
Modified: compiler-rt/trunk/test/asan/TestCases/Linux/static_tls.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/Linux/static_tls.cc?rev=252738&r1=252737&r2=252738&view=diff
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/Linux/static_tls.cc (original)
+++ compiler-rt/trunk/test/asan/TestCases/Linux/static_tls.cc Wed Nov 11 09:37:47 2015
@@ -9,7 +9,7 @@
// CHECK: __tls_get_addr: static tls
// CHECK: after
-// XFAIL: powerpc64, aarch64
+// XFAIL: aarch64
#ifndef SHARED
#include <stdio.h>
More information about the llvm-commits
mailing list