diff options
author | dim <dim@FreeBSD.org> | 2015-02-22 22:53:51 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2015-02-22 22:53:51 +0000 |
commit | 77928dd8d2eecaaa4ba3e4124a3fa0d46c125b39 (patch) | |
tree | c254fae694bb993aff7aa8399e49954202cc40eb /contrib/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cc | |
parent | 64036a7c35233ad0f5289d81af95a2b7023eee7e (diff) | |
parent | d423c65af723ebf09d0356d1833a035e7c6e7aad (diff) | |
download | FreeBSD-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.cc | 44 |
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) { |