summaryrefslogtreecommitdiffstats
path: root/contrib/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cc
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2015-02-22 22:53:51 +0000
committerdim <dim@FreeBSD.org>2015-02-22 22:53:51 +0000
commit77928dd8d2eecaaa4ba3e4124a3fa0d46c125b39 (patch)
treec254fae694bb993aff7aa8399e49954202cc40eb /contrib/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cc
parent64036a7c35233ad0f5289d81af95a2b7023eee7e (diff)
parentd423c65af723ebf09d0356d1833a035e7c6e7aad (diff)
downloadFreeBSD-src-77928dd8d2eecaaa4ba3e4124a3fa0d46c125b39.zip
FreeBSD-src-77928dd8d2eecaaa4ba3e4124a3fa0d46c125b39.tar.gz
Update compiler-rt to trunk r230183. This has some of our patches
imported, so we have just a few small diffs against upstream left.
Diffstat (limited to 'contrib/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cc')
-rw-r--r--contrib/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cc44
1 files changed, 42 insertions, 2 deletions
diff --git a/contrib/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cc b/contrib/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cc
index df42c36..c71b625 100644
--- a/contrib/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cc
+++ b/contrib/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cc
@@ -168,6 +168,20 @@ static uptr g_tls_size;
# define DL_INTERNAL_FUNCTION
#endif
+#if defined(__mips__)
+// 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;
+ const uptr kTlsAlign = 16;
+ const uptr kTlsPreTcbSize =
+ (ThreadDescriptorSize() + kTcbHead + kTlsAlign - 1) & ~(kTlsAlign - 1);
+ InitTlsSize();
+ g_tls_size = (g_tls_size + kTlsPreTcbSize + kTlsAlign -1) & ~(kTlsAlign - 1);
+ return kTlsPreTcbSize;
+}
+#endif
+
void InitTlsSize() {
#if !SANITIZER_FREEBSD && !SANITIZER_ANDROID && !SANITIZER_GO
typedef void (*get_tls_func)(size_t*, size_t*) DL_INTERNAL_FUNCTION;
@@ -184,7 +198,8 @@ void InitTlsSize() {
#endif // !SANITIZER_FREEBSD && !SANITIZER_ANDROID
}
-#if (defined(__x86_64__) || defined(__i386__)) && SANITIZER_LINUX
+#if (defined(__x86_64__) || defined(__i386__) || defined(__mips__)) \
+ && SANITIZER_LINUX
// sizeof(struct thread) from glibc.
static atomic_uintptr_t kThreadDescriptorSize;
@@ -192,6 +207,7 @@ uptr ThreadDescriptorSize() {
uptr val = atomic_load(&kThreadDescriptorSize, memory_order_relaxed);
if (val)
return val;
+#if defined(__x86_64__) || defined(__i386__)
#ifdef _CS_GNU_LIBC_VERSION
char buf[64];
uptr len = confstr(_CS_GNU_LIBC_VERSION, buf, sizeof(buf));
@@ -224,6 +240,13 @@ uptr ThreadDescriptorSize() {
return val;
}
#endif
+#elif defined(__mips__)
+ // TODO(sagarthakur): add more values as per different glibc versions.
+ val = FIRST_32_SECOND_64(1152, 1776);
+ if (val)
+ atomic_store(&kThreadDescriptorSize, val, memory_order_relaxed);
+ return val;
+#endif
return 0;
}
@@ -240,12 +263,24 @@ uptr ThreadSelf() {
asm("mov %%gs:%c1,%0" : "=r"(descr_addr) : "i"(kThreadSelfOffset));
# elif defined(__x86_64__)
asm("mov %%fs:%c1,%0" : "=r"(descr_addr) : "i"(kThreadSelfOffset));
+# elif defined(__mips__)
+ // MIPS uses TLS variant I. The thread pointer (in hardware register $29)
+ // 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 volatile(".set push;\
+ .set mips64r2;\
+ rdhwr %0,$29;\
+ .set pop" : "=r" (thread_pointer));
+ descr_addr = thread_pointer - kTlsTcbOffset - TlsPreTcbSize();
# else
# error "unsupported CPU arch"
# endif
return descr_addr;
}
-#endif // (defined(__x86_64__) || defined(__i386__)) && SANITIZER_LINUX
+#endif // (x86_64 || i386 || MIPS) && SANITIZER_LINUX
#if SANITIZER_FREEBSD
static void **ThreadSelfSegbase() {
@@ -275,6 +310,9 @@ static void GetTls(uptr *addr, uptr *size) {
*size = GetTlsSize();
*addr -= *size;
*addr += ThreadDescriptorSize();
+# elif defined(__mips__)
+ *addr = ThreadSelf();
+ *size = GetTlsSize();
# else
*addr = 0;
*size = 0;
@@ -298,6 +336,7 @@ static void GetTls(uptr *addr, uptr *size) {
}
#endif
+#if !SANITIZER_GO
uptr GetTlsSize() {
#if SANITIZER_FREEBSD
uptr addr, size;
@@ -307,6 +346,7 @@ uptr GetTlsSize() {
return g_tls_size;
#endif
}
+#endif
void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size,
uptr *tls_addr, uptr *tls_size) {
OpenPOWER on IntegriCloud