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