gcc/gcc7-pr79341.patch

85 lines
3.5 KiB
Diff

2017-02-08 Jakub Jelinek <jakub@redhat.com>
PR sanitizer/79341
* sanitizer_common/sanitizer_common_interceptors.inc
(INIT_TLS_GET_ADDR): INTERCEPT_FUNCTION __tls_get_offset rather than
__tls_get_addr_internal.
(__tls_get_addr_internal): Call __tls_get_offset_wrapper with
REAL(__tls_get_offset) as another arugment instead of calling
REAL(__tls_get_addr_internal).
(__tls_get_offset): Call __tls_get_addr_hidden instead of
__interceptor___tls_get_addr_internal_protected.
(__tls_get_offset_wrapper): New function.
--- libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc.jj 2017-02-07 11:08:15.000000000 -0500
+++ libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc 2017-02-08 05:28:58.656850984 -0500
@@ -4550,11 +4550,15 @@ void *__tls_get_addr_opt(void *arg);
// descriptor offset as an argument instead of a pointer. GOT address
// is passed in r12, so it's necessary to write it in assembly. This is
// the function used by the compiler.
-#define INIT_TLS_GET_ADDR COMMON_INTERCEPT_FUNCTION(__tls_get_addr_internal)
+extern "C" uptr __tls_get_offset_wrapper (void *arg, uptr (*fn) (void *));
+#define INIT_TLS_GET_ADDR COMMON_INTERCEPT_FUNCTION(__tls_get_offset)
+DEFINE_REAL(uptr, __tls_get_offset, void *arg)
+extern "C" uptr __tls_get_offset (void *arg);
+extern "C" uptr __interceptor___tls_get_offset (void *arg);
INTERCEPTOR(uptr, __tls_get_addr_internal, void *arg) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, __tls_get_addr_internal, arg);
- uptr res = REAL(__tls_get_addr_internal)(arg);
+ uptr res = __tls_get_offset_wrapper(arg, REAL(__tls_get_offset));
uptr tp = reinterpret_cast<uptr>(__builtin_thread_pointer());
void *ptr = reinterpret_cast<void *>(res + tp);
uptr tls_begin, tls_end;
@@ -4569,29 +4573,42 @@ INTERCEPTOR(uptr, __tls_get_addr_interna
// We need a protected symbol aliasing the above, so that we can jump
// directly to it from the assembly below.
extern "C" __attribute__((alias("__interceptor___tls_get_addr_internal"),
- visibility("protected")))
-uptr __interceptor___tls_get_addr_internal_protected(void *arg);
+ visibility("hidden")))
+uptr __tls_get_addr_hidden(void *arg);
// Now carefully intercept __tls_get_offset.
asm(
".text\n"
- ".global __tls_get_offset\n"
- "__tls_get_offset:\n"
// The __intercept_ version has to exist, so that gen_dynamic_list.py
// exports our symbol.
+ ".weak __tls_get_offset\n"
+ ".type __tls_get_offset, @function\n"
+ "__tls_get_offset:\n"
".global __interceptor___tls_get_offset\n"
+ ".type __interceptor___tls_get_offset, @function\n"
"__interceptor___tls_get_offset:\n"
#ifdef __s390x__
"la %r2, 0(%r2,%r12)\n"
- "jg __interceptor___tls_get_addr_internal_protected\n"
+ "jg __tls_get_addr_hidden\n"
#else
"basr %r3,0\n"
"0: la %r2,0(%r2,%r12)\n"
"l %r4,1f-0b(%r3)\n"
"b 0(%r4,%r3)\n"
- "1: .long __interceptor___tls_get_addr_internal_protected - 0b\n"
+ "1: .long __tls_get_addr_hidden - 0b\n"
#endif
- ".type __tls_get_offset, @function\n"
- ".size __tls_get_offset, .-__tls_get_offset\n"
+ ".size __interceptor___tls_get_offset, .-__interceptor___tls_get_offset\n"
+// Assembly wrapper to call REAL(__tls_get_offset)(arg)
+ ".type __tls_get_offset_wrapper, @function\n"
+ "__tls_get_offset_wrapper:\n"
+#ifdef __s390x__
+ "sgr %r2,%r12\n"
+ "lgr %r1,%r3\n"
+#else
+ "sr %r2,%r12\n"
+ "lr %r1,%r3\n"
+#endif
+ "br %r1\n"
+ ".size __tls_get_offset_wrapper, .-__tls_get_offset_wrapper\n"
);
#endif // SANITIZER_S390
#else