xref: /freebsd/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_interface.inc (revision 0eae32dcef82f6f06de6419a0d623d7def0cc8f6)
1349cc55cSDimitry Andric//===-- tsan_interface.inc --------------------------------------*- C++ -*-===//
2349cc55cSDimitry Andric//
3349cc55cSDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4349cc55cSDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
5349cc55cSDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6349cc55cSDimitry Andric//
7349cc55cSDimitry Andric//===----------------------------------------------------------------------===//
8349cc55cSDimitry Andric//
9349cc55cSDimitry Andric// This file is a part of ThreadSanitizer (TSan), a race detector.
10349cc55cSDimitry Andric//
11349cc55cSDimitry Andric//===----------------------------------------------------------------------===//
12349cc55cSDimitry Andric
13349cc55cSDimitry Andric#include "sanitizer_common/sanitizer_ptrauth.h"
14349cc55cSDimitry Andric#include "tsan_interface.h"
15349cc55cSDimitry Andric#include "tsan_rtl.h"
16349cc55cSDimitry Andric
17349cc55cSDimitry Andric#define CALLERPC ((uptr)__builtin_return_address(0))
18349cc55cSDimitry Andric
19349cc55cSDimitry Andricusing namespace __tsan;
20349cc55cSDimitry Andric
21349cc55cSDimitry Andricvoid __tsan_read1(void *addr) {
22349cc55cSDimitry Andric  MemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 1, kAccessRead);
23349cc55cSDimitry Andric}
24349cc55cSDimitry Andric
25349cc55cSDimitry Andricvoid __tsan_read2(void *addr) {
26349cc55cSDimitry Andric  MemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 2, kAccessRead);
27349cc55cSDimitry Andric}
28349cc55cSDimitry Andric
29349cc55cSDimitry Andricvoid __tsan_read4(void *addr) {
30349cc55cSDimitry Andric  MemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 4, kAccessRead);
31349cc55cSDimitry Andric}
32349cc55cSDimitry Andric
33349cc55cSDimitry Andricvoid __tsan_read8(void *addr) {
34349cc55cSDimitry Andric  MemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 8, kAccessRead);
35349cc55cSDimitry Andric}
36349cc55cSDimitry Andric
37*0eae32dcSDimitry Andricvoid __tsan_read16(void *addr) {
38*0eae32dcSDimitry Andric  MemoryAccess16(cur_thread(), CALLERPC, (uptr)addr, kAccessRead);
39*0eae32dcSDimitry Andric}
40*0eae32dcSDimitry Andric
41349cc55cSDimitry Andricvoid __tsan_write1(void *addr) {
42349cc55cSDimitry Andric  MemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 1, kAccessWrite);
43349cc55cSDimitry Andric}
44349cc55cSDimitry Andric
45349cc55cSDimitry Andricvoid __tsan_write2(void *addr) {
46349cc55cSDimitry Andric  MemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 2, kAccessWrite);
47349cc55cSDimitry Andric}
48349cc55cSDimitry Andric
49349cc55cSDimitry Andricvoid __tsan_write4(void *addr) {
50349cc55cSDimitry Andric  MemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 4, kAccessWrite);
51349cc55cSDimitry Andric}
52349cc55cSDimitry Andric
53349cc55cSDimitry Andricvoid __tsan_write8(void *addr) {
54349cc55cSDimitry Andric  MemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 8, kAccessWrite);
55349cc55cSDimitry Andric}
56349cc55cSDimitry Andric
57*0eae32dcSDimitry Andricvoid __tsan_write16(void *addr) {
58*0eae32dcSDimitry Andric  MemoryAccess16(cur_thread(), CALLERPC, (uptr)addr, kAccessWrite);
59*0eae32dcSDimitry Andric}
60*0eae32dcSDimitry Andric
61349cc55cSDimitry Andricvoid __tsan_read1_pc(void *addr, void *pc) {
62349cc55cSDimitry Andric  MemoryAccess(cur_thread(), STRIP_PAC_PC(pc), (uptr)addr, 1, kAccessRead | kAccessExternalPC);
63349cc55cSDimitry Andric}
64349cc55cSDimitry Andric
65349cc55cSDimitry Andricvoid __tsan_read2_pc(void *addr, void *pc) {
66349cc55cSDimitry Andric  MemoryAccess(cur_thread(), STRIP_PAC_PC(pc), (uptr)addr, 2, kAccessRead | kAccessExternalPC);
67349cc55cSDimitry Andric}
68349cc55cSDimitry Andric
69349cc55cSDimitry Andricvoid __tsan_read4_pc(void *addr, void *pc) {
70349cc55cSDimitry Andric  MemoryAccess(cur_thread(), STRIP_PAC_PC(pc), (uptr)addr, 4, kAccessRead | kAccessExternalPC);
71349cc55cSDimitry Andric}
72349cc55cSDimitry Andric
73349cc55cSDimitry Andricvoid __tsan_read8_pc(void *addr, void *pc) {
74349cc55cSDimitry Andric  MemoryAccess(cur_thread(), STRIP_PAC_PC(pc), (uptr)addr, 8, kAccessRead | kAccessExternalPC);
75349cc55cSDimitry Andric}
76349cc55cSDimitry Andric
77349cc55cSDimitry Andricvoid __tsan_write1_pc(void *addr, void *pc) {
78349cc55cSDimitry Andric  MemoryAccess(cur_thread(), STRIP_PAC_PC(pc), (uptr)addr, 1, kAccessWrite | kAccessExternalPC);
79349cc55cSDimitry Andric}
80349cc55cSDimitry Andric
81349cc55cSDimitry Andricvoid __tsan_write2_pc(void *addr, void *pc) {
82349cc55cSDimitry Andric  MemoryAccess(cur_thread(), STRIP_PAC_PC(pc), (uptr)addr, 2, kAccessWrite | kAccessExternalPC);
83349cc55cSDimitry Andric}
84349cc55cSDimitry Andric
85349cc55cSDimitry Andricvoid __tsan_write4_pc(void *addr, void *pc) {
86349cc55cSDimitry Andric  MemoryAccess(cur_thread(), STRIP_PAC_PC(pc), (uptr)addr, 4, kAccessWrite | kAccessExternalPC);
87349cc55cSDimitry Andric}
88349cc55cSDimitry Andric
89349cc55cSDimitry Andricvoid __tsan_write8_pc(void *addr, void *pc) {
90349cc55cSDimitry Andric  MemoryAccess(cur_thread(), STRIP_PAC_PC(pc), (uptr)addr, 8, kAccessWrite | kAccessExternalPC);
91349cc55cSDimitry Andric}
92349cc55cSDimitry Andric
93349cc55cSDimitry AndricALWAYS_INLINE USED void __tsan_unaligned_read2(const void *addr) {
94349cc55cSDimitry Andric  UnalignedMemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 2, kAccessRead);
95349cc55cSDimitry Andric}
96349cc55cSDimitry Andric
97349cc55cSDimitry AndricALWAYS_INLINE USED void __tsan_unaligned_read4(const void *addr) {
98349cc55cSDimitry Andric  UnalignedMemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 4, kAccessRead);
99349cc55cSDimitry Andric}
100349cc55cSDimitry Andric
101349cc55cSDimitry AndricALWAYS_INLINE USED void __tsan_unaligned_read8(const void *addr) {
102349cc55cSDimitry Andric  UnalignedMemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 8, kAccessRead);
103349cc55cSDimitry Andric}
104349cc55cSDimitry Andric
105349cc55cSDimitry AndricALWAYS_INLINE USED void __tsan_unaligned_write2(void *addr) {
106349cc55cSDimitry Andric  UnalignedMemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 2, kAccessWrite);
107349cc55cSDimitry Andric}
108349cc55cSDimitry Andric
109349cc55cSDimitry AndricALWAYS_INLINE USED void __tsan_unaligned_write4(void *addr) {
110349cc55cSDimitry Andric  UnalignedMemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 4, kAccessWrite);
111349cc55cSDimitry Andric}
112349cc55cSDimitry Andric
113349cc55cSDimitry AndricALWAYS_INLINE USED void __tsan_unaligned_write8(void *addr) {
114349cc55cSDimitry Andric  UnalignedMemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 8, kAccessWrite);
115349cc55cSDimitry Andric}
116349cc55cSDimitry Andric
117349cc55cSDimitry Andricextern "C" {
118349cc55cSDimitry Andric// __sanitizer_unaligned_load/store are for user instrumentation.
119349cc55cSDimitry AndricSANITIZER_INTERFACE_ATTRIBUTE
120349cc55cSDimitry Andricu16 __sanitizer_unaligned_load16(const uu16 *addr) {
121349cc55cSDimitry Andric  __tsan_unaligned_read2(addr);
122349cc55cSDimitry Andric  return *addr;
123349cc55cSDimitry Andric}
124349cc55cSDimitry Andric
125349cc55cSDimitry AndricSANITIZER_INTERFACE_ATTRIBUTE
126349cc55cSDimitry Andricu32 __sanitizer_unaligned_load32(const uu32 *addr) {
127349cc55cSDimitry Andric  __tsan_unaligned_read4(addr);
128349cc55cSDimitry Andric  return *addr;
129349cc55cSDimitry Andric}
130349cc55cSDimitry Andric
131349cc55cSDimitry AndricSANITIZER_INTERFACE_ATTRIBUTE
132349cc55cSDimitry Andricu64 __sanitizer_unaligned_load64(const uu64 *addr) {
133349cc55cSDimitry Andric  __tsan_unaligned_read8(addr);
134349cc55cSDimitry Andric  return *addr;
135349cc55cSDimitry Andric}
136349cc55cSDimitry Andric
137349cc55cSDimitry AndricSANITIZER_INTERFACE_ATTRIBUTE
138349cc55cSDimitry Andricvoid __sanitizer_unaligned_store16(uu16 *addr, u16 v) {
139349cc55cSDimitry Andric  *addr = v;
140349cc55cSDimitry Andric  __tsan_unaligned_write2(addr);
141349cc55cSDimitry Andric}
142349cc55cSDimitry Andric
143349cc55cSDimitry AndricSANITIZER_INTERFACE_ATTRIBUTE
144349cc55cSDimitry Andricvoid __sanitizer_unaligned_store32(uu32 *addr, u32 v) {
145349cc55cSDimitry Andric  *addr = v;
146349cc55cSDimitry Andric  __tsan_unaligned_write4(addr);
147349cc55cSDimitry Andric}
148349cc55cSDimitry Andric
149349cc55cSDimitry AndricSANITIZER_INTERFACE_ATTRIBUTE
150349cc55cSDimitry Andricvoid __sanitizer_unaligned_store64(uu64 *addr, u64 v) {
151349cc55cSDimitry Andric  *addr = v;
152349cc55cSDimitry Andric  __tsan_unaligned_write8(addr);
153349cc55cSDimitry Andric}
154349cc55cSDimitry Andric}
155349cc55cSDimitry Andric
156349cc55cSDimitry Andricvoid __tsan_vptr_update(void **vptr_p, void *new_val) {
157349cc55cSDimitry Andric  if (*vptr_p == new_val)
158349cc55cSDimitry Andric    return;
159349cc55cSDimitry Andric  MemoryAccess(cur_thread(), CALLERPC, (uptr)vptr_p, sizeof(*vptr_p),
160349cc55cSDimitry Andric               kAccessWrite | kAccessVptr);
161349cc55cSDimitry Andric}
162349cc55cSDimitry Andric
163349cc55cSDimitry Andricvoid __tsan_vptr_read(void **vptr_p) {
164349cc55cSDimitry Andric  MemoryAccess(cur_thread(), CALLERPC, (uptr)vptr_p, sizeof(*vptr_p),
165349cc55cSDimitry Andric               kAccessRead | kAccessVptr);
166349cc55cSDimitry Andric}
167349cc55cSDimitry Andric
168349cc55cSDimitry Andricvoid __tsan_func_entry(void *pc) { FuncEntry(cur_thread(), STRIP_PAC_PC(pc)); }
169349cc55cSDimitry Andric
170349cc55cSDimitry Andricvoid __tsan_func_exit() { FuncExit(cur_thread()); }
171349cc55cSDimitry Andric
172349cc55cSDimitry Andricvoid __tsan_ignore_thread_begin() { ThreadIgnoreBegin(cur_thread(), CALLERPC); }
173349cc55cSDimitry Andric
174349cc55cSDimitry Andricvoid __tsan_ignore_thread_end() { ThreadIgnoreEnd(cur_thread()); }
175349cc55cSDimitry Andric
176349cc55cSDimitry Andricvoid __tsan_read_range(void *addr, uptr size) {
177349cc55cSDimitry Andric  MemoryAccessRange(cur_thread(), CALLERPC, (uptr)addr, size, false);
178349cc55cSDimitry Andric}
179349cc55cSDimitry Andric
180349cc55cSDimitry Andricvoid __tsan_write_range(void *addr, uptr size) {
181349cc55cSDimitry Andric  MemoryAccessRange(cur_thread(), CALLERPC, (uptr)addr, size, true);
182349cc55cSDimitry Andric}
183349cc55cSDimitry Andric
184349cc55cSDimitry Andricvoid __tsan_read_range_pc(void *addr, uptr size, void *pc) {
185349cc55cSDimitry Andric  MemoryAccessRange(cur_thread(), STRIP_PAC_PC(pc), (uptr)addr, size, false);
186349cc55cSDimitry Andric}
187349cc55cSDimitry Andric
188349cc55cSDimitry Andricvoid __tsan_write_range_pc(void *addr, uptr size, void *pc) {
189349cc55cSDimitry Andric  MemoryAccessRange(cur_thread(), STRIP_PAC_PC(pc), (uptr)addr, size, true);
190349cc55cSDimitry Andric}
191