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