168d75effSDimitry Andric //===-- dd_interceptors.cpp -----------------------------------------------===//
268d75effSDimitry Andric //
368d75effSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
468d75effSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
568d75effSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
668d75effSDimitry Andric //
768d75effSDimitry Andric //===----------------------------------------------------------------------===//
868d75effSDimitry Andric
9e8d8bef9SDimitry Andric #include <pthread.h>
10e8d8bef9SDimitry Andric
1168d75effSDimitry Andric #include "dd_rtl.h"
1268d75effSDimitry Andric #include "interception/interception.h"
13e8d8bef9SDimitry Andric #include "sanitizer_common/sanitizer_allocator_internal.h"
1468d75effSDimitry Andric #include "sanitizer_common/sanitizer_procmaps.h"
1568d75effSDimitry Andric
1668d75effSDimitry Andric using namespace __dsan;
1768d75effSDimitry Andric
1868d75effSDimitry Andric __attribute__((tls_model("initial-exec")))
1968d75effSDimitry Andric static __thread Thread *thr;
2068d75effSDimitry Andric __attribute__((tls_model("initial-exec")))
2168d75effSDimitry Andric static __thread volatile int initing;
2268d75effSDimitry Andric static bool inited;
2368d75effSDimitry Andric static uptr g_data_start;
2468d75effSDimitry Andric static uptr g_data_end;
2568d75effSDimitry Andric
InitThread()2668d75effSDimitry Andric static bool InitThread() {
2768d75effSDimitry Andric if (initing)
2868d75effSDimitry Andric return false;
2968d75effSDimitry Andric if (thr != 0)
3068d75effSDimitry Andric return true;
3168d75effSDimitry Andric initing = true;
3268d75effSDimitry Andric if (!inited) {
3368d75effSDimitry Andric inited = true;
3468d75effSDimitry Andric Initialize();
3568d75effSDimitry Andric }
3668d75effSDimitry Andric thr = (Thread*)InternalAlloc(sizeof(*thr));
3768d75effSDimitry Andric internal_memset(thr, 0, sizeof(*thr));
3868d75effSDimitry Andric ThreadInit(thr);
3968d75effSDimitry Andric initing = false;
4068d75effSDimitry Andric return true;
4168d75effSDimitry Andric }
4268d75effSDimitry Andric
INTERCEPTOR(int,pthread_mutex_destroy,pthread_mutex_t * m)4368d75effSDimitry Andric INTERCEPTOR(int, pthread_mutex_destroy, pthread_mutex_t *m) {
4468d75effSDimitry Andric InitThread();
4568d75effSDimitry Andric MutexDestroy(thr, (uptr)m);
4668d75effSDimitry Andric return REAL(pthread_mutex_destroy)(m);
4768d75effSDimitry Andric }
4868d75effSDimitry Andric
INTERCEPTOR(int,pthread_mutex_lock,pthread_mutex_t * m)4968d75effSDimitry Andric INTERCEPTOR(int, pthread_mutex_lock, pthread_mutex_t *m) {
5068d75effSDimitry Andric InitThread();
5168d75effSDimitry Andric MutexBeforeLock(thr, (uptr)m, true);
5268d75effSDimitry Andric int res = REAL(pthread_mutex_lock)(m);
5368d75effSDimitry Andric MutexAfterLock(thr, (uptr)m, true, false);
5468d75effSDimitry Andric return res;
5568d75effSDimitry Andric }
5668d75effSDimitry Andric
INTERCEPTOR(int,pthread_mutex_trylock,pthread_mutex_t * m)5768d75effSDimitry Andric INTERCEPTOR(int, pthread_mutex_trylock, pthread_mutex_t *m) {
5868d75effSDimitry Andric InitThread();
5968d75effSDimitry Andric int res = REAL(pthread_mutex_trylock)(m);
6068d75effSDimitry Andric if (res == 0)
6168d75effSDimitry Andric MutexAfterLock(thr, (uptr)m, true, true);
6268d75effSDimitry Andric return res;
6368d75effSDimitry Andric }
6468d75effSDimitry Andric
INTERCEPTOR(int,pthread_mutex_unlock,pthread_mutex_t * m)6568d75effSDimitry Andric INTERCEPTOR(int, pthread_mutex_unlock, pthread_mutex_t *m) {
6668d75effSDimitry Andric InitThread();
6768d75effSDimitry Andric MutexBeforeUnlock(thr, (uptr)m, true);
6868d75effSDimitry Andric return REAL(pthread_mutex_unlock)(m);
6968d75effSDimitry Andric }
7068d75effSDimitry Andric
INTERCEPTOR(int,pthread_spin_destroy,pthread_spinlock_t * m)7168d75effSDimitry Andric INTERCEPTOR(int, pthread_spin_destroy, pthread_spinlock_t *m) {
7268d75effSDimitry Andric InitThread();
7368d75effSDimitry Andric int res = REAL(pthread_spin_destroy)(m);
7468d75effSDimitry Andric MutexDestroy(thr, (uptr)m);
7568d75effSDimitry Andric return res;
7668d75effSDimitry Andric }
7768d75effSDimitry Andric
INTERCEPTOR(int,pthread_spin_lock,pthread_spinlock_t * m)7868d75effSDimitry Andric INTERCEPTOR(int, pthread_spin_lock, pthread_spinlock_t *m) {
7968d75effSDimitry Andric InitThread();
8068d75effSDimitry Andric MutexBeforeLock(thr, (uptr)m, true);
8168d75effSDimitry Andric int res = REAL(pthread_spin_lock)(m);
8268d75effSDimitry Andric MutexAfterLock(thr, (uptr)m, true, false);
8368d75effSDimitry Andric return res;
8468d75effSDimitry Andric }
8568d75effSDimitry Andric
INTERCEPTOR(int,pthread_spin_trylock,pthread_spinlock_t * m)8668d75effSDimitry Andric INTERCEPTOR(int, pthread_spin_trylock, pthread_spinlock_t *m) {
8768d75effSDimitry Andric InitThread();
8868d75effSDimitry Andric int res = REAL(pthread_spin_trylock)(m);
8968d75effSDimitry Andric if (res == 0)
9068d75effSDimitry Andric MutexAfterLock(thr, (uptr)m, true, true);
9168d75effSDimitry Andric return res;
9268d75effSDimitry Andric }
9368d75effSDimitry Andric
INTERCEPTOR(int,pthread_spin_unlock,pthread_spinlock_t * m)9468d75effSDimitry Andric INTERCEPTOR(int, pthread_spin_unlock, pthread_spinlock_t *m) {
9568d75effSDimitry Andric InitThread();
9668d75effSDimitry Andric MutexBeforeUnlock(thr, (uptr)m, true);
9768d75effSDimitry Andric return REAL(pthread_spin_unlock)(m);
9868d75effSDimitry Andric }
9968d75effSDimitry Andric
INTERCEPTOR(int,pthread_rwlock_destroy,pthread_rwlock_t * m)10068d75effSDimitry Andric INTERCEPTOR(int, pthread_rwlock_destroy, pthread_rwlock_t *m) {
10168d75effSDimitry Andric InitThread();
10268d75effSDimitry Andric MutexDestroy(thr, (uptr)m);
10368d75effSDimitry Andric return REAL(pthread_rwlock_destroy)(m);
10468d75effSDimitry Andric }
10568d75effSDimitry Andric
INTERCEPTOR(int,pthread_rwlock_rdlock,pthread_rwlock_t * m)10668d75effSDimitry Andric INTERCEPTOR(int, pthread_rwlock_rdlock, pthread_rwlock_t *m) {
10768d75effSDimitry Andric InitThread();
10868d75effSDimitry Andric MutexBeforeLock(thr, (uptr)m, false);
10968d75effSDimitry Andric int res = REAL(pthread_rwlock_rdlock)(m);
11068d75effSDimitry Andric MutexAfterLock(thr, (uptr)m, false, false);
11168d75effSDimitry Andric return res;
11268d75effSDimitry Andric }
11368d75effSDimitry Andric
INTERCEPTOR(int,pthread_rwlock_tryrdlock,pthread_rwlock_t * m)11468d75effSDimitry Andric INTERCEPTOR(int, pthread_rwlock_tryrdlock, pthread_rwlock_t *m) {
11568d75effSDimitry Andric InitThread();
11668d75effSDimitry Andric int res = REAL(pthread_rwlock_tryrdlock)(m);
11768d75effSDimitry Andric if (res == 0)
11868d75effSDimitry Andric MutexAfterLock(thr, (uptr)m, false, true);
11968d75effSDimitry Andric return res;
12068d75effSDimitry Andric }
12168d75effSDimitry Andric
INTERCEPTOR(int,pthread_rwlock_timedrdlock,pthread_rwlock_t * m,const timespec * abstime)12268d75effSDimitry Andric INTERCEPTOR(int, pthread_rwlock_timedrdlock, pthread_rwlock_t *m,
12368d75effSDimitry Andric const timespec *abstime) {
12468d75effSDimitry Andric InitThread();
12568d75effSDimitry Andric int res = REAL(pthread_rwlock_timedrdlock)(m, abstime);
12668d75effSDimitry Andric if (res == 0)
12768d75effSDimitry Andric MutexAfterLock(thr, (uptr)m, false, true);
12868d75effSDimitry Andric return res;
12968d75effSDimitry Andric }
13068d75effSDimitry Andric
INTERCEPTOR(int,pthread_rwlock_wrlock,pthread_rwlock_t * m)13168d75effSDimitry Andric INTERCEPTOR(int, pthread_rwlock_wrlock, pthread_rwlock_t *m) {
13268d75effSDimitry Andric InitThread();
13368d75effSDimitry Andric MutexBeforeLock(thr, (uptr)m, true);
13468d75effSDimitry Andric int res = REAL(pthread_rwlock_wrlock)(m);
13568d75effSDimitry Andric MutexAfterLock(thr, (uptr)m, true, false);
13668d75effSDimitry Andric return res;
13768d75effSDimitry Andric }
13868d75effSDimitry Andric
INTERCEPTOR(int,pthread_rwlock_trywrlock,pthread_rwlock_t * m)13968d75effSDimitry Andric INTERCEPTOR(int, pthread_rwlock_trywrlock, pthread_rwlock_t *m) {
14068d75effSDimitry Andric InitThread();
14168d75effSDimitry Andric int res = REAL(pthread_rwlock_trywrlock)(m);
14268d75effSDimitry Andric if (res == 0)
14368d75effSDimitry Andric MutexAfterLock(thr, (uptr)m, true, true);
14468d75effSDimitry Andric return res;
14568d75effSDimitry Andric }
14668d75effSDimitry Andric
INTERCEPTOR(int,pthread_rwlock_timedwrlock,pthread_rwlock_t * m,const timespec * abstime)14768d75effSDimitry Andric INTERCEPTOR(int, pthread_rwlock_timedwrlock, pthread_rwlock_t *m,
14868d75effSDimitry Andric const timespec *abstime) {
14968d75effSDimitry Andric InitThread();
15068d75effSDimitry Andric int res = REAL(pthread_rwlock_timedwrlock)(m, abstime);
15168d75effSDimitry Andric if (res == 0)
15268d75effSDimitry Andric MutexAfterLock(thr, (uptr)m, true, true);
15368d75effSDimitry Andric return res;
15468d75effSDimitry Andric }
15568d75effSDimitry Andric
INTERCEPTOR(int,pthread_rwlock_unlock,pthread_rwlock_t * m)15668d75effSDimitry Andric INTERCEPTOR(int, pthread_rwlock_unlock, pthread_rwlock_t *m) {
15768d75effSDimitry Andric InitThread();
15868d75effSDimitry Andric MutexBeforeUnlock(thr, (uptr)m, true); // note: not necessary write unlock
15968d75effSDimitry Andric return REAL(pthread_rwlock_unlock)(m);
16068d75effSDimitry Andric }
16168d75effSDimitry Andric
init_cond(pthread_cond_t * c,bool force=false)16268d75effSDimitry Andric static pthread_cond_t *init_cond(pthread_cond_t *c, bool force = false) {
16368d75effSDimitry Andric atomic_uintptr_t *p = (atomic_uintptr_t*)c;
16468d75effSDimitry Andric uptr cond = atomic_load(p, memory_order_acquire);
16568d75effSDimitry Andric if (!force && cond != 0)
16668d75effSDimitry Andric return (pthread_cond_t*)cond;
167e8d8bef9SDimitry Andric void *newcond = InternalAlloc(sizeof(pthread_cond_t));
16868d75effSDimitry Andric internal_memset(newcond, 0, sizeof(pthread_cond_t));
16968d75effSDimitry Andric if (atomic_compare_exchange_strong(p, &cond, (uptr)newcond,
17068d75effSDimitry Andric memory_order_acq_rel))
17168d75effSDimitry Andric return (pthread_cond_t*)newcond;
172e8d8bef9SDimitry Andric InternalFree(newcond);
17368d75effSDimitry Andric return (pthread_cond_t*)cond;
17468d75effSDimitry Andric }
17568d75effSDimitry Andric
INTERCEPTOR(int,pthread_cond_init,pthread_cond_t * c,const pthread_condattr_t * a)17668d75effSDimitry Andric INTERCEPTOR(int, pthread_cond_init, pthread_cond_t *c,
17768d75effSDimitry Andric const pthread_condattr_t *a) {
17868d75effSDimitry Andric InitThread();
17968d75effSDimitry Andric pthread_cond_t *cond = init_cond(c, true);
18068d75effSDimitry Andric return REAL(pthread_cond_init)(cond, a);
18168d75effSDimitry Andric }
18268d75effSDimitry Andric
INTERCEPTOR(int,pthread_cond_wait,pthread_cond_t * c,pthread_mutex_t * m)18368d75effSDimitry Andric INTERCEPTOR(int, pthread_cond_wait, pthread_cond_t *c, pthread_mutex_t *m) {
18468d75effSDimitry Andric InitThread();
18568d75effSDimitry Andric pthread_cond_t *cond = init_cond(c);
18668d75effSDimitry Andric MutexBeforeUnlock(thr, (uptr)m, true);
18768d75effSDimitry Andric MutexBeforeLock(thr, (uptr)m, true);
18868d75effSDimitry Andric int res = REAL(pthread_cond_wait)(cond, m);
18968d75effSDimitry Andric MutexAfterLock(thr, (uptr)m, true, false);
19068d75effSDimitry Andric return res;
19168d75effSDimitry Andric }
19268d75effSDimitry Andric
INTERCEPTOR(int,pthread_cond_timedwait,pthread_cond_t * c,pthread_mutex_t * m,const timespec * abstime)19368d75effSDimitry Andric INTERCEPTOR(int, pthread_cond_timedwait, pthread_cond_t *c, pthread_mutex_t *m,
19468d75effSDimitry Andric const timespec *abstime) {
19568d75effSDimitry Andric InitThread();
19668d75effSDimitry Andric pthread_cond_t *cond = init_cond(c);
19768d75effSDimitry Andric MutexBeforeUnlock(thr, (uptr)m, true);
19868d75effSDimitry Andric MutexBeforeLock(thr, (uptr)m, true);
19968d75effSDimitry Andric int res = REAL(pthread_cond_timedwait)(cond, m, abstime);
20068d75effSDimitry Andric MutexAfterLock(thr, (uptr)m, true, false);
20168d75effSDimitry Andric return res;
20268d75effSDimitry Andric }
20368d75effSDimitry Andric
INTERCEPTOR(int,pthread_cond_signal,pthread_cond_t * c)20468d75effSDimitry Andric INTERCEPTOR(int, pthread_cond_signal, pthread_cond_t *c) {
20568d75effSDimitry Andric InitThread();
20668d75effSDimitry Andric pthread_cond_t *cond = init_cond(c);
20768d75effSDimitry Andric return REAL(pthread_cond_signal)(cond);
20868d75effSDimitry Andric }
20968d75effSDimitry Andric
INTERCEPTOR(int,pthread_cond_broadcast,pthread_cond_t * c)21068d75effSDimitry Andric INTERCEPTOR(int, pthread_cond_broadcast, pthread_cond_t *c) {
21168d75effSDimitry Andric InitThread();
21268d75effSDimitry Andric pthread_cond_t *cond = init_cond(c);
21368d75effSDimitry Andric return REAL(pthread_cond_broadcast)(cond);
21468d75effSDimitry Andric }
21568d75effSDimitry Andric
INTERCEPTOR(int,pthread_cond_destroy,pthread_cond_t * c)21668d75effSDimitry Andric INTERCEPTOR(int, pthread_cond_destroy, pthread_cond_t *c) {
21768d75effSDimitry Andric InitThread();
21868d75effSDimitry Andric pthread_cond_t *cond = init_cond(c);
21968d75effSDimitry Andric int res = REAL(pthread_cond_destroy)(cond);
220e8d8bef9SDimitry Andric InternalFree(cond);
22168d75effSDimitry Andric atomic_store((atomic_uintptr_t*)c, 0, memory_order_relaxed);
22268d75effSDimitry Andric return res;
22368d75effSDimitry Andric }
22468d75effSDimitry Andric
22568d75effSDimitry Andric // for symbolizer
INTERCEPTOR(char *,realpath,const char * path,char * resolved_path)22668d75effSDimitry Andric INTERCEPTOR(char*, realpath, const char *path, char *resolved_path) {
22768d75effSDimitry Andric InitThread();
22868d75effSDimitry Andric return REAL(realpath)(path, resolved_path);
22968d75effSDimitry Andric }
23068d75effSDimitry Andric
INTERCEPTOR(SSIZE_T,read,int fd,void * ptr,SIZE_T count)23168d75effSDimitry Andric INTERCEPTOR(SSIZE_T, read, int fd, void *ptr, SIZE_T count) {
23268d75effSDimitry Andric InitThread();
23368d75effSDimitry Andric return REAL(read)(fd, ptr, count);
23468d75effSDimitry Andric }
23568d75effSDimitry Andric
INTERCEPTOR(SSIZE_T,pread,int fd,void * ptr,SIZE_T count,OFF_T offset)23668d75effSDimitry Andric INTERCEPTOR(SSIZE_T, pread, int fd, void *ptr, SIZE_T count, OFF_T offset) {
23768d75effSDimitry Andric InitThread();
23868d75effSDimitry Andric return REAL(pread)(fd, ptr, count, offset);
23968d75effSDimitry Andric }
24068d75effSDimitry Andric
24168d75effSDimitry Andric extern "C" {
__dsan_before_mutex_lock(uptr m,int writelock)24268d75effSDimitry Andric void __dsan_before_mutex_lock(uptr m, int writelock) {
24368d75effSDimitry Andric if (!InitThread())
24468d75effSDimitry Andric return;
24568d75effSDimitry Andric MutexBeforeLock(thr, m, writelock);
24668d75effSDimitry Andric }
24768d75effSDimitry Andric
__dsan_after_mutex_lock(uptr m,int writelock,int trylock)24868d75effSDimitry Andric void __dsan_after_mutex_lock(uptr m, int writelock, int trylock) {
24968d75effSDimitry Andric if (!InitThread())
25068d75effSDimitry Andric return;
25168d75effSDimitry Andric MutexAfterLock(thr, m, writelock, trylock);
25268d75effSDimitry Andric }
25368d75effSDimitry Andric
__dsan_before_mutex_unlock(uptr m,int writelock)25468d75effSDimitry Andric void __dsan_before_mutex_unlock(uptr m, int writelock) {
25568d75effSDimitry Andric if (!InitThread())
25668d75effSDimitry Andric return;
25768d75effSDimitry Andric MutexBeforeUnlock(thr, m, writelock);
25868d75effSDimitry Andric }
25968d75effSDimitry Andric
__dsan_mutex_destroy(uptr m)26068d75effSDimitry Andric void __dsan_mutex_destroy(uptr m) {
26168d75effSDimitry Andric if (!InitThread())
26268d75effSDimitry Andric return;
26368d75effSDimitry Andric // if (m >= g_data_start && m < g_data_end)
26468d75effSDimitry Andric // return;
26568d75effSDimitry Andric MutexDestroy(thr, m);
26668d75effSDimitry Andric }
26768d75effSDimitry Andric } // extern "C"
26868d75effSDimitry Andric
26968d75effSDimitry Andric namespace __dsan {
27068d75effSDimitry Andric
InitDataSeg()27168d75effSDimitry Andric static void InitDataSeg() {
27268d75effSDimitry Andric MemoryMappingLayout proc_maps(true);
27368d75effSDimitry Andric char name[128];
27468d75effSDimitry Andric MemoryMappedSegment segment(name, ARRAY_SIZE(name));
27568d75effSDimitry Andric bool prev_is_data = false;
27668d75effSDimitry Andric while (proc_maps.Next(&segment)) {
27768d75effSDimitry Andric bool is_data = segment.offset != 0 && segment.filename[0] != 0;
27868d75effSDimitry Andric // BSS may get merged with [heap] in /proc/self/maps. This is not very
27968d75effSDimitry Andric // reliable.
28068d75effSDimitry Andric bool is_bss = segment.offset == 0 &&
28168d75effSDimitry Andric (segment.filename[0] == 0 ||
28268d75effSDimitry Andric internal_strcmp(segment.filename, "[heap]") == 0) &&
28368d75effSDimitry Andric prev_is_data;
28468d75effSDimitry Andric if (g_data_start == 0 && is_data) g_data_start = segment.start;
28568d75effSDimitry Andric if (is_bss) g_data_end = segment.end;
28668d75effSDimitry Andric prev_is_data = is_data;
28768d75effSDimitry Andric }
288*349cc55cSDimitry Andric VPrintf(1, "guessed data_start=0x%zx data_end=0x%zx\n", g_data_start,
289*349cc55cSDimitry Andric g_data_end);
29068d75effSDimitry Andric CHECK_LT(g_data_start, g_data_end);
29168d75effSDimitry Andric CHECK_GE((uptr)&g_data_start, g_data_start);
29268d75effSDimitry Andric CHECK_LT((uptr)&g_data_start, g_data_end);
29368d75effSDimitry Andric }
29468d75effSDimitry Andric
InitializeInterceptors()29568d75effSDimitry Andric void InitializeInterceptors() {
29668d75effSDimitry Andric INTERCEPT_FUNCTION(pthread_mutex_destroy);
29768d75effSDimitry Andric INTERCEPT_FUNCTION(pthread_mutex_lock);
29868d75effSDimitry Andric INTERCEPT_FUNCTION(pthread_mutex_trylock);
29968d75effSDimitry Andric INTERCEPT_FUNCTION(pthread_mutex_unlock);
30068d75effSDimitry Andric
30168d75effSDimitry Andric INTERCEPT_FUNCTION(pthread_spin_destroy);
30268d75effSDimitry Andric INTERCEPT_FUNCTION(pthread_spin_lock);
30368d75effSDimitry Andric INTERCEPT_FUNCTION(pthread_spin_trylock);
30468d75effSDimitry Andric INTERCEPT_FUNCTION(pthread_spin_unlock);
30568d75effSDimitry Andric
30668d75effSDimitry Andric INTERCEPT_FUNCTION(pthread_rwlock_destroy);
30768d75effSDimitry Andric INTERCEPT_FUNCTION(pthread_rwlock_rdlock);
30868d75effSDimitry Andric INTERCEPT_FUNCTION(pthread_rwlock_tryrdlock);
30968d75effSDimitry Andric INTERCEPT_FUNCTION(pthread_rwlock_timedrdlock);
31068d75effSDimitry Andric INTERCEPT_FUNCTION(pthread_rwlock_wrlock);
31168d75effSDimitry Andric INTERCEPT_FUNCTION(pthread_rwlock_trywrlock);
31268d75effSDimitry Andric INTERCEPT_FUNCTION(pthread_rwlock_timedwrlock);
31368d75effSDimitry Andric INTERCEPT_FUNCTION(pthread_rwlock_unlock);
31468d75effSDimitry Andric
31568d75effSDimitry Andric INTERCEPT_FUNCTION_VER(pthread_cond_init, "GLIBC_2.3.2");
31668d75effSDimitry Andric INTERCEPT_FUNCTION_VER(pthread_cond_signal, "GLIBC_2.3.2");
31768d75effSDimitry Andric INTERCEPT_FUNCTION_VER(pthread_cond_broadcast, "GLIBC_2.3.2");
31868d75effSDimitry Andric INTERCEPT_FUNCTION_VER(pthread_cond_wait, "GLIBC_2.3.2");
31968d75effSDimitry Andric INTERCEPT_FUNCTION_VER(pthread_cond_timedwait, "GLIBC_2.3.2");
32068d75effSDimitry Andric INTERCEPT_FUNCTION_VER(pthread_cond_destroy, "GLIBC_2.3.2");
32168d75effSDimitry Andric
32268d75effSDimitry Andric // for symbolizer
32368d75effSDimitry Andric INTERCEPT_FUNCTION(realpath);
32468d75effSDimitry Andric INTERCEPT_FUNCTION(read);
32568d75effSDimitry Andric INTERCEPT_FUNCTION(pread);
32668d75effSDimitry Andric
32768d75effSDimitry Andric InitDataSeg();
32868d75effSDimitry Andric }
32968d75effSDimitry Andric
33068d75effSDimitry Andric } // namespace __dsan
331