1#ifndef TSAN_INTERCEPTORS_H
2#define TSAN_INTERCEPTORS_H
3
4#include "sanitizer_common/sanitizer_stacktrace.h"
5#include "tsan_rtl.h"
6
7namespace __tsan {
8
9class ScopedInterceptor {
10 public:
11  ScopedInterceptor(ThreadState *thr, const char *fname, uptr pc);
12  ~ScopedInterceptor();
13  void DisableIgnores() {
14    if (UNLIKELY(ignoring_))
15      DisableIgnoresImpl();
16  }
17  void EnableIgnores() {
18    if (UNLIKELY(ignoring_))
19      EnableIgnoresImpl();
20  }
21
22 private:
23  ThreadState *const thr_;
24  bool in_ignored_lib_;
25  bool ignoring_;
26
27  void DisableIgnoresImpl();
28  void EnableIgnoresImpl();
29};
30
31LibIgnore *libignore();
32
33#if !SANITIZER_GO
34inline bool in_symbolizer() {
35  return UNLIKELY(cur_thread_init()->in_symbolizer);
36}
37#endif
38
39}  // namespace __tsan
40
41#define SCOPED_INTERCEPTOR_RAW(func, ...)            \
42  ThreadState *thr = cur_thread_init();              \
43  ScopedInterceptor si(thr, #func, GET_CALLER_PC()); \
44  UNUSED const uptr pc = GET_CURRENT_PC();
45
46#ifdef __powerpc64__
47// Debugging of crashes on powerpc after commit:
48// c80604f7a3 ("tsan: remove real func check from interceptors")
49// Somehow replacing if with DCHECK leads to strange failures in:
50// SanitizerCommon-tsan-powerpc64le-Linux :: Linux/ptrace.cpp
51// https://lab.llvm.org/buildbot/#/builders/105
52// https://lab.llvm.org/buildbot/#/builders/121
53// https://lab.llvm.org/buildbot/#/builders/57
54#  define CHECK_REAL_FUNC(func)                                          \
55    if (REAL(func) == 0) {                                               \
56      Report("FATAL: ThreadSanitizer: failed to intercept %s\n", #func); \
57      Die();                                                             \
58    }
59#else
60#  define CHECK_REAL_FUNC(func) DCHECK(REAL(func))
61#endif
62
63#define SCOPED_TSAN_INTERCEPTOR(func, ...)                                \
64  SCOPED_INTERCEPTOR_RAW(func, __VA_ARGS__);                              \
65  CHECK_REAL_FUNC(func);                                                  \
66  if (!thr->is_inited || thr->ignore_interceptors || thr->in_ignored_lib) \
67    return REAL(func)(__VA_ARGS__);
68
69#define SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START() \
70    si.DisableIgnores();
71
72#define SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_END() \
73    si.EnableIgnores();
74
75#define TSAN_INTERCEPTOR(ret, func, ...) INTERCEPTOR(ret, func, __VA_ARGS__)
76
77#if SANITIZER_NETBSD
78# define TSAN_INTERCEPTOR_NETBSD_ALIAS(ret, func, ...) \
79  TSAN_INTERCEPTOR(ret, __libc_##func, __VA_ARGS__) \
80  ALIAS(WRAPPER_NAME(pthread_##func));
81# define TSAN_INTERCEPTOR_NETBSD_ALIAS_THR(ret, func, ...) \
82  TSAN_INTERCEPTOR(ret, __libc_thr_##func, __VA_ARGS__) \
83  ALIAS(WRAPPER_NAME(pthread_##func));
84# define TSAN_INTERCEPTOR_NETBSD_ALIAS_THR2(ret, func, func2, ...) \
85  TSAN_INTERCEPTOR(ret, __libc_thr_##func, __VA_ARGS__) \
86  ALIAS(WRAPPER_NAME(pthread_##func2));
87#else
88# define TSAN_INTERCEPTOR_NETBSD_ALIAS(ret, func, ...)
89# define TSAN_INTERCEPTOR_NETBSD_ALIAS_THR(ret, func, ...)
90# define TSAN_INTERCEPTOR_NETBSD_ALIAS_THR2(ret, func, func2, ...)
91#endif
92
93#endif  // TSAN_INTERCEPTORS_H
94