xref: /openbsd-src/gnu/llvm/compiler-rt/lib/tsan/rtl/tsan_interceptors.h (revision 810390e339a5425391477d5d41c78d7cab2424ac)
13cab2bb3Spatrick #ifndef TSAN_INTERCEPTORS_H
23cab2bb3Spatrick #define TSAN_INTERCEPTORS_H
33cab2bb3Spatrick 
43cab2bb3Spatrick #include "sanitizer_common/sanitizer_stacktrace.h"
53cab2bb3Spatrick #include "tsan_rtl.h"
63cab2bb3Spatrick 
73cab2bb3Spatrick namespace __tsan {
83cab2bb3Spatrick 
93cab2bb3Spatrick class ScopedInterceptor {
103cab2bb3Spatrick  public:
113cab2bb3Spatrick   ScopedInterceptor(ThreadState *thr, const char *fname, uptr pc);
123cab2bb3Spatrick   ~ScopedInterceptor();
DisableIgnores()13*810390e3Srobert   void DisableIgnores() {
14*810390e3Srobert     if (UNLIKELY(ignoring_))
15*810390e3Srobert       DisableIgnoresImpl();
16*810390e3Srobert   }
EnableIgnores()17*810390e3Srobert   void EnableIgnores() {
18*810390e3Srobert     if (UNLIKELY(ignoring_))
19*810390e3Srobert       EnableIgnoresImpl();
20*810390e3Srobert   }
21*810390e3Srobert 
223cab2bb3Spatrick  private:
233cab2bb3Spatrick   ThreadState *const thr_;
24*810390e3Srobert   bool in_ignored_lib_ = false;
25*810390e3Srobert   bool in_blocking_func_ = false;
26*810390e3Srobert   bool ignoring_ = false;
27*810390e3Srobert 
28*810390e3Srobert   void DisableIgnoresImpl();
29*810390e3Srobert   void EnableIgnoresImpl();
303cab2bb3Spatrick };
313cab2bb3Spatrick 
323cab2bb3Spatrick LibIgnore *libignore();
333cab2bb3Spatrick 
343cab2bb3Spatrick #if !SANITIZER_GO
in_symbolizer()35d89ec533Spatrick inline bool in_symbolizer() {
36*810390e3Srobert   return UNLIKELY(cur_thread_init()->in_symbolizer);
373cab2bb3Spatrick }
383cab2bb3Spatrick #endif
393cab2bb3Spatrick 
MustIgnoreInterceptor(ThreadState * thr)40*810390e3Srobert inline bool MustIgnoreInterceptor(ThreadState *thr) {
41*810390e3Srobert   return !thr->is_inited || thr->ignore_interceptors || thr->in_ignored_lib;
42*810390e3Srobert }
43*810390e3Srobert 
443cab2bb3Spatrick }  // namespace __tsan
453cab2bb3Spatrick 
463cab2bb3Spatrick #define SCOPED_INTERCEPTOR_RAW(func, ...)            \
47*810390e3Srobert   ThreadState *thr = cur_thread_init();              \
48*810390e3Srobert   ScopedInterceptor si(thr, #func, GET_CALLER_PC()); \
49*810390e3Srobert   UNUSED const uptr pc = GET_CURRENT_PC();
503cab2bb3Spatrick 
51*810390e3Srobert #ifdef __powerpc64__
52*810390e3Srobert // Debugging of crashes on powerpc after commit:
53*810390e3Srobert // c80604f7a3 ("tsan: remove real func check from interceptors")
54*810390e3Srobert // Somehow replacing if with DCHECK leads to strange failures in:
55*810390e3Srobert // SanitizerCommon-tsan-powerpc64le-Linux :: Linux/ptrace.cpp
56*810390e3Srobert // https://lab.llvm.org/buildbot/#/builders/105
57*810390e3Srobert // https://lab.llvm.org/buildbot/#/builders/121
58*810390e3Srobert // https://lab.llvm.org/buildbot/#/builders/57
59*810390e3Srobert #  define CHECK_REAL_FUNC(func)                                          \
603cab2bb3Spatrick     if (REAL(func) == 0) {                                               \
613cab2bb3Spatrick       Report("FATAL: ThreadSanitizer: failed to intercept %s\n", #func); \
623cab2bb3Spatrick       Die();                                                             \
63*810390e3Srobert     }
64*810390e3Srobert #else
65*810390e3Srobert #  define CHECK_REAL_FUNC(func) DCHECK(REAL(func))
66*810390e3Srobert #endif
67*810390e3Srobert 
68*810390e3Srobert #define SCOPED_TSAN_INTERCEPTOR(func, ...)   \
69*810390e3Srobert   SCOPED_INTERCEPTOR_RAW(func, __VA_ARGS__); \
70*810390e3Srobert   CHECK_REAL_FUNC(func);                     \
71*810390e3Srobert   if (MustIgnoreInterceptor(thr))            \
72*810390e3Srobert     return REAL(func)(__VA_ARGS__);
733cab2bb3Spatrick 
743cab2bb3Spatrick #define SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START() \
753cab2bb3Spatrick     si.DisableIgnores();
763cab2bb3Spatrick 
773cab2bb3Spatrick #define SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_END() \
783cab2bb3Spatrick     si.EnableIgnores();
793cab2bb3Spatrick 
803cab2bb3Spatrick #define TSAN_INTERCEPTOR(ret, func, ...) INTERCEPTOR(ret, func, __VA_ARGS__)
813cab2bb3Spatrick 
82*810390e3Srobert #if SANITIZER_FREEBSD
83*810390e3Srobert #  define TSAN_INTERCEPTOR_FREEBSD_ALIAS(ret, func, ...) \
84*810390e3Srobert     TSAN_INTERCEPTOR(ret, _pthread_##func, __VA_ARGS__)  \
85*810390e3Srobert     ALIAS(WRAPPER_NAME(pthread_##func));
86*810390e3Srobert #else
87*810390e3Srobert #  define TSAN_INTERCEPTOR_FREEBSD_ALIAS(ret, func, ...)
88*810390e3Srobert #endif
89*810390e3Srobert 
903cab2bb3Spatrick #if SANITIZER_NETBSD
913cab2bb3Spatrick # define TSAN_INTERCEPTOR_NETBSD_ALIAS(ret, func, ...) \
923cab2bb3Spatrick   TSAN_INTERCEPTOR(ret, __libc_##func, __VA_ARGS__) \
933cab2bb3Spatrick   ALIAS(WRAPPER_NAME(pthread_##func));
943cab2bb3Spatrick # define TSAN_INTERCEPTOR_NETBSD_ALIAS_THR(ret, func, ...) \
953cab2bb3Spatrick   TSAN_INTERCEPTOR(ret, __libc_thr_##func, __VA_ARGS__) \
963cab2bb3Spatrick   ALIAS(WRAPPER_NAME(pthread_##func));
973cab2bb3Spatrick # define TSAN_INTERCEPTOR_NETBSD_ALIAS_THR2(ret, func, func2, ...) \
983cab2bb3Spatrick   TSAN_INTERCEPTOR(ret, __libc_thr_##func, __VA_ARGS__) \
993cab2bb3Spatrick   ALIAS(WRAPPER_NAME(pthread_##func2));
1003cab2bb3Spatrick #else
1013cab2bb3Spatrick # define TSAN_INTERCEPTOR_NETBSD_ALIAS(ret, func, ...)
1023cab2bb3Spatrick # define TSAN_INTERCEPTOR_NETBSD_ALIAS_THR(ret, func, ...)
1033cab2bb3Spatrick # define TSAN_INTERCEPTOR_NETBSD_ALIAS_THR2(ret, func, func2, ...)
1043cab2bb3Spatrick #endif
1053cab2bb3Spatrick 
1063cab2bb3Spatrick #endif  // TSAN_INTERCEPTORS_H
107