1 //===-- tsan_interface_inl.h ------------------------------------*- C++ -*-===// 2 // 3 // This file is distributed under the University of Illinois Open Source 4 // License. See LICENSE.TXT for details. 5 // 6 //===----------------------------------------------------------------------===// 7 // 8 // This file is a part of ThreadSanitizer (TSan), a race detector. 9 // 10 //===----------------------------------------------------------------------===// 11 12 #include "tsan_interface.h" 13 #include "tsan_rtl.h" 14 15 #define CALLERPC ((uptr)__builtin_return_address(0)) 16 17 using namespace __tsan; // NOLINT 18 19 void __tsan_read1(void *addr) { 20 MemoryRead(cur_thread(), CALLERPC, (uptr)addr, kSizeLog1); 21 } 22 23 void __tsan_read2(void *addr) { 24 MemoryRead(cur_thread(), CALLERPC, (uptr)addr, kSizeLog2); 25 } 26 27 void __tsan_read4(void *addr) { 28 MemoryRead(cur_thread(), CALLERPC, (uptr)addr, kSizeLog4); 29 } 30 31 void __tsan_read8(void *addr) { 32 MemoryRead(cur_thread(), CALLERPC, (uptr)addr, kSizeLog8); 33 } 34 35 void __tsan_write1(void *addr) { 36 MemoryWrite(cur_thread(), CALLERPC, (uptr)addr, kSizeLog1); 37 } 38 39 void __tsan_write2(void *addr) { 40 MemoryWrite(cur_thread(), CALLERPC, (uptr)addr, kSizeLog2); 41 } 42 43 void __tsan_write4(void *addr) { 44 MemoryWrite(cur_thread(), CALLERPC, (uptr)addr, kSizeLog4); 45 } 46 47 void __tsan_write8(void *addr) { 48 MemoryWrite(cur_thread(), CALLERPC, (uptr)addr, kSizeLog8); 49 } 50 51 void __tsan_read1_pc(void *addr, void *pc) { 52 MemoryRead(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog1); 53 } 54 55 void __tsan_read2_pc(void *addr, void *pc) { 56 MemoryRead(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog2); 57 } 58 59 void __tsan_read4_pc(void *addr, void *pc) { 60 MemoryRead(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog4); 61 } 62 63 void __tsan_read8_pc(void *addr, void *pc) { 64 MemoryRead(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog8); 65 } 66 67 void __tsan_write1_pc(void *addr, void *pc) { 68 MemoryWrite(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog1); 69 } 70 71 void __tsan_write2_pc(void *addr, void *pc) { 72 MemoryWrite(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog2); 73 } 74 75 void __tsan_write4_pc(void *addr, void *pc) { 76 MemoryWrite(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog4); 77 } 78 79 void __tsan_write8_pc(void *addr, void *pc) { 80 MemoryWrite(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog8); 81 } 82 83 void __tsan_vptr_update(void **vptr_p, void *new_val) { 84 CHECK_EQ(sizeof(vptr_p), 8); 85 if (*vptr_p != new_val) { 86 ThreadState *thr = cur_thread(); 87 thr->is_vptr_access = true; 88 MemoryWrite(thr, CALLERPC, (uptr)vptr_p, kSizeLog8); 89 thr->is_vptr_access = false; 90 } 91 } 92 93 void __tsan_vptr_read(void **vptr_p) { 94 CHECK_EQ(sizeof(vptr_p), 8); 95 ThreadState *thr = cur_thread(); 96 thr->is_vptr_access = true; 97 MemoryRead(thr, CALLERPC, (uptr)vptr_p, kSizeLog8); 98 thr->is_vptr_access = false; 99 } 100 101 void __tsan_func_entry(void *pc) { 102 FuncEntry(cur_thread(), (uptr)pc); 103 } 104 105 void __tsan_func_exit() { 106 FuncExit(cur_thread()); 107 } 108 109 void __tsan_ignore_thread_begin() { 110 ThreadIgnoreBegin(cur_thread(), CALLERPC); 111 } 112 113 void __tsan_ignore_thread_end() { 114 ThreadIgnoreEnd(cur_thread(), CALLERPC); 115 } 116 117 void __tsan_read_range(void *addr, uptr size) { 118 MemoryAccessRange(cur_thread(), CALLERPC, (uptr)addr, size, false); 119 } 120 121 void __tsan_write_range(void *addr, uptr size) { 122 MemoryAccessRange(cur_thread(), CALLERPC, (uptr)addr, size, true); 123 } 124