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
18using namespace __tsan;  // NOLINT
19
20void __tsan_read1(void *addr) {
21  MemoryRead(cur_thread(), CALLERPC, (uptr)addr, kSizeLog1);
22}
23
24void __tsan_read2(void *addr) {
25  MemoryRead(cur_thread(), CALLERPC, (uptr)addr, kSizeLog2);
26}
27
28void __tsan_read4(void *addr) {
29  MemoryRead(cur_thread(), CALLERPC, (uptr)addr, kSizeLog4);
30}
31
32void __tsan_read8(void *addr) {
33  MemoryRead(cur_thread(), CALLERPC, (uptr)addr, kSizeLog8);
34}
35
36void __tsan_write1(void *addr) {
37  MemoryWrite(cur_thread(), CALLERPC, (uptr)addr, kSizeLog1);
38}
39
40void __tsan_write2(void *addr) {
41  MemoryWrite(cur_thread(), CALLERPC, (uptr)addr, kSizeLog2);
42}
43
44void __tsan_write4(void *addr) {
45  MemoryWrite(cur_thread(), CALLERPC, (uptr)addr, kSizeLog4);
46}
47
48void __tsan_write8(void *addr) {
49  MemoryWrite(cur_thread(), CALLERPC, (uptr)addr, kSizeLog8);
50}
51
52void __tsan_read1_pc(void *addr, void *pc) {
53  MemoryRead(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog1);
54}
55
56void __tsan_read2_pc(void *addr, void *pc) {
57  MemoryRead(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog2);
58}
59
60void __tsan_read4_pc(void *addr, void *pc) {
61  MemoryRead(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog4);
62}
63
64void __tsan_read8_pc(void *addr, void *pc) {
65  MemoryRead(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog8);
66}
67
68void __tsan_write1_pc(void *addr, void *pc) {
69  MemoryWrite(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog1);
70}
71
72void __tsan_write2_pc(void *addr, void *pc) {
73  MemoryWrite(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog2);
74}
75
76void __tsan_write4_pc(void *addr, void *pc) {
77  MemoryWrite(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog4);
78}
79
80void __tsan_write8_pc(void *addr, void *pc) {
81  MemoryWrite(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog8);
82}
83
84void __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
94void __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
102void __tsan_func_entry(void *pc) {
103  FuncEntry(cur_thread(), (uptr)pc);
104}
105
106void __tsan_func_exit() {
107  FuncExit(cur_thread());
108}
109
110void __tsan_ignore_thread_begin() {
111  ThreadIgnoreBegin(cur_thread(), CALLERPC);
112}
113
114void __tsan_ignore_thread_end() {
115  ThreadIgnoreEnd(cur_thread(), CALLERPC);
116}
117
118void __tsan_read_range(void *addr, uptr size) {
119  MemoryAccessRange(cur_thread(), CALLERPC, (uptr)addr, size, false);
120}
121
122void __tsan_write_range(void *addr, uptr size) {
123  MemoryAccessRange(cur_thread(), CALLERPC, (uptr)addr, size, true);
124}
125