forked from OSchip/llvm-project
[TSan] Intercept __tls_get_addr_internal and __tls_get_offset on SystemZ
Reuse the assembly glue code from sanitizer_common_interceptors.inc and the handling logic from the __tls_get_addr interceptor. Reviewed By: dvyukov Differential Revision: https://reviews.llvm.org/D105629
This commit is contained in:
parent
b17673816d
commit
bd77f742d6
|
@ -5303,6 +5303,12 @@ INTERCEPTOR(__sanitizer_clock_t, times, void *tms) {
|
|||
#define INIT_TIMES
|
||||
#endif
|
||||
|
||||
#if SANITIZER_S390 && \
|
||||
(SANITIZER_INTERCEPT_TLS_GET_ADDR || SANITIZER_INTERCEPT_TLS_GET_OFFSET)
|
||||
extern "C" uptr __tls_get_offset_wrapper(void *arg, uptr (*fn)(void *arg));
|
||||
DEFINE_REAL(uptr, __tls_get_offset, void *arg)
|
||||
#endif
|
||||
|
||||
#if SANITIZER_INTERCEPT_TLS_GET_ADDR
|
||||
#if !SANITIZER_S390
|
||||
#define INIT_TLS_GET_ADDR COMMON_INTERCEPT_FUNCTION(__tls_get_addr)
|
||||
|
@ -5342,11 +5348,7 @@ 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.
|
||||
extern "C" uptr __tls_get_offset_wrapper(void *arg, uptr (*fn)(void *arg));
|
||||
#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);
|
||||
|
@ -5362,6 +5364,15 @@ INTERCEPTOR(uptr, __tls_get_addr_internal, void *arg) {
|
|||
}
|
||||
return res;
|
||||
}
|
||||
#endif // SANITIZER_S390
|
||||
#else
|
||||
#define INIT_TLS_GET_ADDR
|
||||
#endif
|
||||
|
||||
#if SANITIZER_S390 && \
|
||||
(SANITIZER_INTERCEPT_TLS_GET_ADDR || SANITIZER_INTERCEPT_TLS_GET_OFFSET)
|
||||
extern "C" uptr __tls_get_offset(void *arg);
|
||||
extern "C" uptr __interceptor___tls_get_offset(void *arg);
|
||||
// We need a hidden 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"),
|
||||
|
@ -5400,9 +5411,6 @@ asm(
|
|||
"br %r3\n"
|
||||
".size __tls_get_offset_wrapper, .-__tls_get_offset_wrapper\n"
|
||||
);
|
||||
#endif // SANITIZER_S390
|
||||
#else
|
||||
#define INIT_TLS_GET_ADDR
|
||||
#endif
|
||||
|
||||
#if SANITIZER_INTERCEPT_LISTXATTR
|
||||
|
|
|
@ -2271,6 +2271,7 @@ static void HandleRecvmsg(ThreadState *thr, uptr pc,
|
|||
#define NEED_TLS_GET_ADDR
|
||||
#endif
|
||||
#undef SANITIZER_INTERCEPT_TLS_GET_ADDR
|
||||
#define SANITIZER_INTERCEPT_TLS_GET_OFFSET 1
|
||||
#undef SANITIZER_INTERCEPT_PTHREAD_SIGMASK
|
||||
|
||||
#define COMMON_INTERCEPT_FUNCTION(name) INTERCEPT_FUNCTION(name)
|
||||
|
@ -2586,6 +2587,20 @@ static void syscall_post_fork(uptr pc, int pid) {
|
|||
#include "sanitizer_common/sanitizer_syscalls_netbsd.inc"
|
||||
|
||||
#ifdef NEED_TLS_GET_ADDR
|
||||
|
||||
static void handle_tls_addr(void *arg, void *res) {
|
||||
ThreadState *thr = cur_thread();
|
||||
if (!thr)
|
||||
return;
|
||||
DTLS::DTV *dtv = DTLS_on_tls_get_addr(arg, res, thr->tls_addr,
|
||||
thr->tls_addr + thr->tls_size);
|
||||
if (!dtv)
|
||||
return;
|
||||
// New DTLS block has been allocated.
|
||||
MemoryResetRange(thr, 0, dtv->beg, dtv->size);
|
||||
}
|
||||
|
||||
#if !SANITIZER_S390
|
||||
// Define own interceptor instead of sanitizer_common's for three reasons:
|
||||
// 1. It must not process pending signals.
|
||||
// Signal handlers may contain MOVDQA instruction (see below).
|
||||
|
@ -2598,17 +2613,17 @@ static void syscall_post_fork(uptr pc, int pid) {
|
|||
// execute MOVDQA with stack addresses.
|
||||
TSAN_INTERCEPTOR(void *, __tls_get_addr, void *arg) {
|
||||
void *res = REAL(__tls_get_addr)(arg);
|
||||
ThreadState *thr = cur_thread();
|
||||
if (!thr)
|
||||
return res;
|
||||
DTLS::DTV *dtv = DTLS_on_tls_get_addr(arg, res, thr->tls_addr,
|
||||
thr->tls_addr + thr->tls_size);
|
||||
if (!dtv)
|
||||
return res;
|
||||
// New DTLS block has been allocated.
|
||||
MemoryResetRange(thr, 0, dtv->beg, dtv->size);
|
||||
handle_tls_addr(arg, res);
|
||||
return res;
|
||||
}
|
||||
#else // SANITIZER_S390
|
||||
TSAN_INTERCEPTOR(uptr, __tls_get_addr_internal, void *arg) {
|
||||
uptr res = __tls_get_offset_wrapper(arg, REAL(__tls_get_offset));
|
||||
char *tp = static_cast<char *>(__builtin_thread_pointer());
|
||||
handle_tls_addr(arg, res + tp);
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if SANITIZER_NETBSD
|
||||
|
@ -2831,7 +2846,12 @@ void InitializeInterceptors() {
|
|||
TSAN_INTERCEPT(_exit);
|
||||
|
||||
#ifdef NEED_TLS_GET_ADDR
|
||||
#if !SANITIZER_S390
|
||||
TSAN_INTERCEPT(__tls_get_addr);
|
||||
#else
|
||||
TSAN_INTERCEPT(__tls_get_addr_internal);
|
||||
TSAN_INTERCEPT(__tls_get_offset);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
TSAN_MAYBE_INTERCEPT__LWP_EXIT;
|
||||
|
|
Loading…
Reference in New Issue