Skip to content

Commit 44809bf

Browse files
committed
s390x __tls_get_addr_internal vs. __tls_get_offset
Summary: Symbol __tls_get_addr_internal is a GLIBC_PRIVATE private symbol on s390{,x}, the glibc folks aren't very happy about asan using it. Additionally, only recent glibc versions have it, older versions just have __tls_get_offset and nothing else. The patch doesn't drop the __tls_get_addr_internal interception altogether, but changes it so that it calls real __tls_get_offset function instead (and much more importantly, that __tls_get_offset interception calls the real __tls_get_offset function). This way it should work also on glibc 2.18 and earlier. See http://gcc.gnu.org/PR79341 for further details. Reviewers: kcc, koriakin Reviewed By: kcc, koriakin Subscribers: kubamracek, mehdi_amini Tags: #sanitizers Differential Revision: https://reviews.llvm.org/D29735 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@294790 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent dcd2129 commit 44809bf

File tree

1 file changed

+26
-11
lines changed

1 file changed

+26
-11
lines changed

lib/sanitizer_common/sanitizer_common_interceptors.inc

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4608,11 +4608,15 @@ void *__tls_get_addr_opt(void *arg);
46084608
// descriptor offset as an argument instead of a pointer. GOT address
46094609
// is passed in r12, so it's necessary to write it in assembly. This is
46104610
// the function used by the compiler.
4611-
#define INIT_TLS_GET_ADDR COMMON_INTERCEPT_FUNCTION(__tls_get_addr_internal)
4611+
extern "C" uptr __tls_get_offset_wrapper(void *arg, uptr (*fn)(void *arg));
4612+
#define INIT_TLS_GET_ADDR COMMON_INTERCEPT_FUNCTION(__tls_get_offset)
4613+
DEFINE_REAL(uptr, __tls_get_offset, void *arg)
4614+
extern "C" uptr __tls_get_offset(void *arg);
4615+
extern "C" uptr __interceptor___tls_get_offset(void *arg);
46124616
INTERCEPTOR(uptr, __tls_get_addr_internal, void *arg) {
46134617
void *ctx;
46144618
COMMON_INTERCEPTOR_ENTER(ctx, __tls_get_addr_internal, arg);
4615-
uptr res = REAL(__tls_get_addr_internal)(arg);
4619+
uptr res = __tls_get_offset_wrapper(arg, REAL(__tls_get_offset));
46164620
uptr tp = reinterpret_cast<uptr>(__builtin_thread_pointer());
46174621
void *ptr = reinterpret_cast<void *>(res + tp);
46184622
uptr tls_begin, tls_end;
@@ -4624,32 +4628,43 @@ INTERCEPTOR(uptr, __tls_get_addr_internal, void *arg) {
46244628
}
46254629
return res;
46264630
}
4627-
// We need a protected symbol aliasing the above, so that we can jump
4631+
// We need a hidden symbol aliasing the above, so that we can jump
46284632
// directly to it from the assembly below.
46294633
extern "C" __attribute__((alias("__interceptor___tls_get_addr_internal"),
4630-
visibility("protected")))
4631-
uptr __interceptor___tls_get_addr_internal_protected(void *arg);
4634+
visibility("hidden")))
4635+
uptr __tls_get_addr_hidden(void *arg);
46324636
// Now carefully intercept __tls_get_offset.
46334637
asm(
46344638
".text\n"
4635-
".global __tls_get_offset\n"
4636-
"__tls_get_offset:\n"
46374639
// The __intercept_ version has to exist, so that gen_dynamic_list.py
46384640
// exports our symbol.
4641+
".weak __tls_get_offset\n"
4642+
".type __tls_get_offset, @function\n"
4643+
"__tls_get_offset:\n"
46394644
".global __interceptor___tls_get_offset\n"
4645+
".type __interceptor___tls_get_offset, @function\n"
46404646
"__interceptor___tls_get_offset:\n"
46414647
#ifdef __s390x__
46424648
"la %r2, 0(%r2,%r12)\n"
4643-
"jg __interceptor___tls_get_addr_internal_protected\n"
4649+
"jg __tls_get_addr_hidden\n"
46444650
#else
46454651
"basr %r3,0\n"
46464652
"0: la %r2,0(%r2,%r12)\n"
46474653
"l %r4,1f-0b(%r3)\n"
46484654
"b 0(%r4,%r3)\n"
4649-
"1: .long __interceptor___tls_get_addr_internal_protected - 0b\n"
4655+
"1: .long __tls_get_addr_hidden - 0b\n"
46504656
#endif
4651-
".type __tls_get_offset, @function\n"
4652-
".size __tls_get_offset, .-__tls_get_offset\n"
4657+
".size __interceptor___tls_get_offset, .-__interceptor___tls_get_offset\n"
4658+
// Assembly wrapper to call REAL(__tls_get_offset)(arg)
4659+
".type __tls_get_offset_wrapper, @function\n"
4660+
"__tls_get_offset_wrapper:\n"
4661+
#ifdef __s390x__
4662+
"sgr %r2,%r12\n"
4663+
#else
4664+
"sr %r2,%r12\n"
4665+
#endif
4666+
"br %r3\n"
4667+
".size __tls_get_offset_wrapper, .-__tls_get_offset_wrapper\n"
46534668
);
46544669
#endif // SANITIZER_S390
46554670
#else

0 commit comments

Comments
 (0)