summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcin Koscielnicki <koriakin@0x04.net>2016-06-21 07:09:36 +0000
committerMarcin Koscielnicki <koriakin@0x04.net>2016-06-21 07:09:36 +0000
commitcf523336808929d11b8f97337a04295ed2681fe4 (patch)
tree1cfc093b7c7c5a303758f25ab66a48030ee7b314
parent05c0c08ed57f6dc959ebd0b2f902d63f1e50613b (diff)
[sanitizers] [PowerPC] Intercept __tls_get_addr_opt.
On PowerPC, if binutils and glibc are new enough, the linker uses an optimized code sequence to implement __tls_get_addr call stub, which will end up calling __tls_get_addr_opt instead of __tls_get_addr. Thus, we need to intercept it in addition to __tls_get_addr. This symbol is actually an alias of __tls_get_addr - its only purpose is that its presence in glibc triggers the optimization in linker. This means we can make our own intercepting symbol an alias as well. This patch will make the linker attempt optimization even on older glibc's (since it sees a defined __tls_get_addr_opt symbol in msan) - however, this is only a very minor performance problem (the linker generated code will never recognize a filled static TLS descriptor, always burning a few cycles), not a correctness problem. This fixes MSan's dtls_test.c, allowing us to finally enable MSan on PowerPC64. git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@273250 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/sanitizer_common/sanitizer_common_interceptors.inc8
1 files changed, 8 insertions, 0 deletions
diff --git a/lib/sanitizer_common/sanitizer_common_interceptors.inc b/lib/sanitizer_common/sanitizer_common_interceptors.inc
index b7664c4e5..b9b157cb5 100644
--- a/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -4435,6 +4435,14 @@ INTERCEPTOR(void *, __tls_get_addr, void *arg) {
}
return res;
}
+#if SANITIZER_PPC
+// On PowerPC, we also need to intercept __tls_get_addr_opt, which has
+// mostly the same semantics as __tls_get_addr, but its presence enables
+// some optimizations in linker (which are safe to ignore here).
+extern "C" __attribute__((alias("__interceptor___tls_get_addr"),
+ visibility("default")))
+void *__tls_get_addr_opt(void *arg);
+#endif
#else // SANITIZER_S390
// On s390, we have to intercept two functions here:
// - __tls_get_addr_internal, which is a glibc-internal function that is like