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