tsan_interface.h revision 360784
1//===-- tsan_interface.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// The functions declared in this header will be inserted by the instrumentation
12// module.
13// This header can be included by the instrumented program or by TSan tests.
14//===----------------------------------------------------------------------===//
15#ifndef TSAN_INTERFACE_H
16#define TSAN_INTERFACE_H
17
18#include <sanitizer_common/sanitizer_internal_defs.h>
19using __sanitizer::uptr;
20using __sanitizer::tid_t;
21
22// This header should NOT include any other headers.
23// All functions in this header are extern "C" and start with __tsan_.
24
25#ifdef __cplusplus
26extern "C" {
27#endif
28
29#if !SANITIZER_GO
30
31// This function should be called at the very beginning of the process,
32// before any instrumented code is executed and before any call to malloc.
33SANITIZER_INTERFACE_ATTRIBUTE void __tsan_init();
34
35SANITIZER_INTERFACE_ATTRIBUTE void __tsan_flush_memory();
36
37SANITIZER_INTERFACE_ATTRIBUTE void __tsan_read1(void *addr);
38SANITIZER_INTERFACE_ATTRIBUTE void __tsan_read2(void *addr);
39SANITIZER_INTERFACE_ATTRIBUTE void __tsan_read4(void *addr);
40SANITIZER_INTERFACE_ATTRIBUTE void __tsan_read8(void *addr);
41SANITIZER_INTERFACE_ATTRIBUTE void __tsan_read16(void *addr);
42
43SANITIZER_INTERFACE_ATTRIBUTE void __tsan_write1(void *addr);
44SANITIZER_INTERFACE_ATTRIBUTE void __tsan_write2(void *addr);
45SANITIZER_INTERFACE_ATTRIBUTE void __tsan_write4(void *addr);
46SANITIZER_INTERFACE_ATTRIBUTE void __tsan_write8(void *addr);
47SANITIZER_INTERFACE_ATTRIBUTE void __tsan_write16(void *addr);
48
49SANITIZER_INTERFACE_ATTRIBUTE void __tsan_unaligned_read2(const void *addr);
50SANITIZER_INTERFACE_ATTRIBUTE void __tsan_unaligned_read4(const void *addr);
51SANITIZER_INTERFACE_ATTRIBUTE void __tsan_unaligned_read8(const void *addr);
52SANITIZER_INTERFACE_ATTRIBUTE void __tsan_unaligned_read16(const void *addr);
53
54SANITIZER_INTERFACE_ATTRIBUTE void __tsan_unaligned_write2(void *addr);
55SANITIZER_INTERFACE_ATTRIBUTE void __tsan_unaligned_write4(void *addr);
56SANITIZER_INTERFACE_ATTRIBUTE void __tsan_unaligned_write8(void *addr);
57SANITIZER_INTERFACE_ATTRIBUTE void __tsan_unaligned_write16(void *addr);
58
59SANITIZER_INTERFACE_ATTRIBUTE void __tsan_read1_pc(void *addr, void *pc);
60SANITIZER_INTERFACE_ATTRIBUTE void __tsan_read2_pc(void *addr, void *pc);
61SANITIZER_INTERFACE_ATTRIBUTE void __tsan_read4_pc(void *addr, void *pc);
62SANITIZER_INTERFACE_ATTRIBUTE void __tsan_read8_pc(void *addr, void *pc);
63SANITIZER_INTERFACE_ATTRIBUTE void __tsan_read16_pc(void *addr, void *pc);
64
65SANITIZER_INTERFACE_ATTRIBUTE void __tsan_write1_pc(void *addr, void *pc);
66SANITIZER_INTERFACE_ATTRIBUTE void __tsan_write2_pc(void *addr, void *pc);
67SANITIZER_INTERFACE_ATTRIBUTE void __tsan_write4_pc(void *addr, void *pc);
68SANITIZER_INTERFACE_ATTRIBUTE void __tsan_write8_pc(void *addr, void *pc);
69SANITIZER_INTERFACE_ATTRIBUTE void __tsan_write16_pc(void *addr, void *pc);
70
71SANITIZER_INTERFACE_ATTRIBUTE void __tsan_vptr_read(void **vptr_p);
72SANITIZER_INTERFACE_ATTRIBUTE
73void __tsan_vptr_update(void **vptr_p, void *new_val);
74
75SANITIZER_INTERFACE_ATTRIBUTE void __tsan_func_entry(void *call_pc);
76SANITIZER_INTERFACE_ATTRIBUTE void __tsan_func_exit();
77
78SANITIZER_INTERFACE_ATTRIBUTE void __tsan_ignore_thread_begin();
79SANITIZER_INTERFACE_ATTRIBUTE void __tsan_ignore_thread_end();
80
81SANITIZER_INTERFACE_ATTRIBUTE
82void *__tsan_external_register_tag(const char *object_type);
83SANITIZER_INTERFACE_ATTRIBUTE
84void __tsan_external_register_header(void *tag, const char *header);
85SANITIZER_INTERFACE_ATTRIBUTE
86void __tsan_external_assign_tag(void *addr, void *tag);
87SANITIZER_INTERFACE_ATTRIBUTE
88void __tsan_external_read(void *addr, void *caller_pc, void *tag);
89SANITIZER_INTERFACE_ATTRIBUTE
90void __tsan_external_write(void *addr, void *caller_pc, void *tag);
91
92SANITIZER_INTERFACE_ATTRIBUTE
93void __tsan_read_range(void *addr, unsigned long size);
94SANITIZER_INTERFACE_ATTRIBUTE
95void __tsan_write_range(void *addr, unsigned long size);
96
97SANITIZER_INTERFACE_ATTRIBUTE
98void __tsan_read_range_pc(void *addr, unsigned long size, void *pc);  // NOLINT
99SANITIZER_INTERFACE_ATTRIBUTE
100void __tsan_write_range_pc(void *addr, unsigned long size, void *pc);  // NOLINT
101
102// User may provide function that would be called right when TSan detects
103// an error. The argument 'report' is an opaque pointer that can be used to
104// gather additional information using other TSan report API functions.
105SANITIZER_INTERFACE_ATTRIBUTE
106void __tsan_on_report(void *report);
107
108// If TSan is currently reporting a detected issue on the current thread,
109// returns an opaque pointer to the current report. Otherwise returns NULL.
110SANITIZER_INTERFACE_ATTRIBUTE
111void *__tsan_get_current_report();
112
113// Returns a report's description (issue type), number of duplicate issues
114// found, counts of array data (stack traces, memory operations, locations,
115// mutexes, threads, unique thread IDs) and a stack trace of a sleep() call (if
116// one was involved in the issue).
117SANITIZER_INTERFACE_ATTRIBUTE
118int __tsan_get_report_data(void *report, const char **description, int *count,
119                           int *stack_count, int *mop_count, int *loc_count,
120                           int *mutex_count, int *thread_count,
121                           int *unique_tid_count, void **sleep_trace,
122                           uptr trace_size);
123
124/// Retrieves the "tag" from a report (for external-race report types). External
125/// races can be associated with a tag which give them more meaning. For example
126/// tag value '1' means "Swift access race". Tag value '0' indicated a plain
127/// external race.
128///
129/// \param report opaque pointer to the current report (obtained as argument in
130///               __tsan_on_report, or from __tsan_get_current_report)
131/// \param [out] tag points to storage that will be filled with the tag value
132///
133/// \returns non-zero value on success, zero on failure
134SANITIZER_INTERFACE_ATTRIBUTE
135int __tsan_get_report_tag(void *report, uptr *tag);
136
137// Returns information about stack traces included in the report.
138SANITIZER_INTERFACE_ATTRIBUTE
139int __tsan_get_report_stack(void *report, uptr idx, void **trace,
140                            uptr trace_size);
141
142// Returns information about memory operations included in the report.
143SANITIZER_INTERFACE_ATTRIBUTE
144int __tsan_get_report_mop(void *report, uptr idx, int *tid, void **addr,
145                          int *size, int *write, int *atomic, void **trace,
146                          uptr trace_size);
147
148// Returns information about locations included in the report.
149SANITIZER_INTERFACE_ATTRIBUTE
150int __tsan_get_report_loc(void *report, uptr idx, const char **type,
151                          void **addr, uptr *start, uptr *size, int *tid,
152                          int *fd, int *suppressable, void **trace,
153                          uptr trace_size);
154
155SANITIZER_INTERFACE_ATTRIBUTE
156int __tsan_get_report_loc_object_type(void *report, uptr idx,
157                                      const char **object_type);
158
159// Returns information about mutexes included in the report.
160SANITIZER_INTERFACE_ATTRIBUTE
161int __tsan_get_report_mutex(void *report, uptr idx, uptr *mutex_id, void **addr,
162                            int *destroyed, void **trace, uptr trace_size);
163
164// Returns information about threads included in the report.
165SANITIZER_INTERFACE_ATTRIBUTE
166int __tsan_get_report_thread(void *report, uptr idx, int *tid, tid_t *os_id,
167                             int *running, const char **name, int *parent_tid,
168                             void **trace, uptr trace_size);
169
170// Returns information about unique thread IDs included in the report.
171SANITIZER_INTERFACE_ATTRIBUTE
172int __tsan_get_report_unique_tid(void *report, uptr idx, int *tid);
173
174// Returns the type of the pointer (heap, stack, global, ...) and if possible
175// also the starting address (e.g. of a heap allocation) and size.
176SANITIZER_INTERFACE_ATTRIBUTE
177const char *__tsan_locate_address(uptr addr, char *name, uptr name_size,
178                                  uptr *region_address, uptr *region_size);
179
180// Returns the allocation stack for a heap pointer.
181SANITIZER_INTERFACE_ATTRIBUTE
182int __tsan_get_alloc_stack(uptr addr, uptr *trace, uptr size, int *thread_id,
183                           tid_t *os_id);
184
185#endif  // SANITIZER_GO
186
187#ifdef __cplusplus
188}  // extern "C"
189#endif
190
191namespace __tsan {
192
193// These should match declarations from public tsan_interface_atomic.h header.
194typedef unsigned char      a8;
195typedef unsigned short a16;
196typedef unsigned int       a32;
197typedef unsigned long long a64;
198#if !SANITIZER_GO && (defined(__SIZEOF_INT128__) \
199    || (__clang_major__ * 100 + __clang_minor__ >= 302)) && !defined(__mips64)
200__extension__ typedef __int128 a128;
201# define __TSAN_HAS_INT128 1
202#else
203# define __TSAN_HAS_INT128 0
204#endif
205
206// Part of ABI, do not change.
207// https://github.com/llvm/llvm-project/blob/master/libcxx/include/atomic
208typedef enum {
209  mo_relaxed,
210  mo_consume,
211  mo_acquire,
212  mo_release,
213  mo_acq_rel,
214  mo_seq_cst
215} morder;
216
217struct ThreadState;
218
219extern "C" {
220SANITIZER_INTERFACE_ATTRIBUTE
221a8 __tsan_atomic8_load(const volatile a8 *a, morder mo);
222SANITIZER_INTERFACE_ATTRIBUTE
223a16 __tsan_atomic16_load(const volatile a16 *a, morder mo);
224SANITIZER_INTERFACE_ATTRIBUTE
225a32 __tsan_atomic32_load(const volatile a32 *a, morder mo);
226SANITIZER_INTERFACE_ATTRIBUTE
227a64 __tsan_atomic64_load(const volatile a64 *a, morder mo);
228#if __TSAN_HAS_INT128
229SANITIZER_INTERFACE_ATTRIBUTE
230a128 __tsan_atomic128_load(const volatile a128 *a, morder mo);
231#endif
232
233SANITIZER_INTERFACE_ATTRIBUTE
234void __tsan_atomic8_store(volatile a8 *a, a8 v, morder mo);
235SANITIZER_INTERFACE_ATTRIBUTE
236void __tsan_atomic16_store(volatile a16 *a, a16 v, morder mo);
237SANITIZER_INTERFACE_ATTRIBUTE
238void __tsan_atomic32_store(volatile a32 *a, a32 v, morder mo);
239SANITIZER_INTERFACE_ATTRIBUTE
240void __tsan_atomic64_store(volatile a64 *a, a64 v, morder mo);
241#if __TSAN_HAS_INT128
242SANITIZER_INTERFACE_ATTRIBUTE
243void __tsan_atomic128_store(volatile a128 *a, a128 v, morder mo);
244#endif
245
246SANITIZER_INTERFACE_ATTRIBUTE
247a8 __tsan_atomic8_exchange(volatile a8 *a, a8 v, morder mo);
248SANITIZER_INTERFACE_ATTRIBUTE
249a16 __tsan_atomic16_exchange(volatile a16 *a, a16 v, morder mo);
250SANITIZER_INTERFACE_ATTRIBUTE
251a32 __tsan_atomic32_exchange(volatile a32 *a, a32 v, morder mo);
252SANITIZER_INTERFACE_ATTRIBUTE
253a64 __tsan_atomic64_exchange(volatile a64 *a, a64 v, morder mo);
254#if __TSAN_HAS_INT128
255SANITIZER_INTERFACE_ATTRIBUTE
256a128 __tsan_atomic128_exchange(volatile a128 *a, a128 v, morder mo);
257#endif
258
259SANITIZER_INTERFACE_ATTRIBUTE
260a8 __tsan_atomic8_fetch_add(volatile a8 *a, a8 v, morder mo);
261SANITIZER_INTERFACE_ATTRIBUTE
262a16 __tsan_atomic16_fetch_add(volatile a16 *a, a16 v, morder mo);
263SANITIZER_INTERFACE_ATTRIBUTE
264a32 __tsan_atomic32_fetch_add(volatile a32 *a, a32 v, morder mo);
265SANITIZER_INTERFACE_ATTRIBUTE
266a64 __tsan_atomic64_fetch_add(volatile a64 *a, a64 v, morder mo);
267#if __TSAN_HAS_INT128
268SANITIZER_INTERFACE_ATTRIBUTE
269a128 __tsan_atomic128_fetch_add(volatile a128 *a, a128 v, morder mo);
270#endif
271
272SANITIZER_INTERFACE_ATTRIBUTE
273a8 __tsan_atomic8_fetch_sub(volatile a8 *a, a8 v, morder mo);
274SANITIZER_INTERFACE_ATTRIBUTE
275a16 __tsan_atomic16_fetch_sub(volatile a16 *a, a16 v, morder mo);
276SANITIZER_INTERFACE_ATTRIBUTE
277a32 __tsan_atomic32_fetch_sub(volatile a32 *a, a32 v, morder mo);
278SANITIZER_INTERFACE_ATTRIBUTE
279a64 __tsan_atomic64_fetch_sub(volatile a64 *a, a64 v, morder mo);
280#if __TSAN_HAS_INT128
281SANITIZER_INTERFACE_ATTRIBUTE
282a128 __tsan_atomic128_fetch_sub(volatile a128 *a, a128 v, morder mo);
283#endif
284
285SANITIZER_INTERFACE_ATTRIBUTE
286a8 __tsan_atomic8_fetch_and(volatile a8 *a, a8 v, morder mo);
287SANITIZER_INTERFACE_ATTRIBUTE
288a16 __tsan_atomic16_fetch_and(volatile a16 *a, a16 v, morder mo);
289SANITIZER_INTERFACE_ATTRIBUTE
290a32 __tsan_atomic32_fetch_and(volatile a32 *a, a32 v, morder mo);
291SANITIZER_INTERFACE_ATTRIBUTE
292a64 __tsan_atomic64_fetch_and(volatile a64 *a, a64 v, morder mo);
293#if __TSAN_HAS_INT128
294SANITIZER_INTERFACE_ATTRIBUTE
295a128 __tsan_atomic128_fetch_and(volatile a128 *a, a128 v, morder mo);
296#endif
297
298SANITIZER_INTERFACE_ATTRIBUTE
299a8 __tsan_atomic8_fetch_or(volatile a8 *a, a8 v, morder mo);
300SANITIZER_INTERFACE_ATTRIBUTE
301a16 __tsan_atomic16_fetch_or(volatile a16 *a, a16 v, morder mo);
302SANITIZER_INTERFACE_ATTRIBUTE
303a32 __tsan_atomic32_fetch_or(volatile a32 *a, a32 v, morder mo);
304SANITIZER_INTERFACE_ATTRIBUTE
305a64 __tsan_atomic64_fetch_or(volatile a64 *a, a64 v, morder mo);
306#if __TSAN_HAS_INT128
307SANITIZER_INTERFACE_ATTRIBUTE
308a128 __tsan_atomic128_fetch_or(volatile a128 *a, a128 v, morder mo);
309#endif
310
311SANITIZER_INTERFACE_ATTRIBUTE
312a8 __tsan_atomic8_fetch_xor(volatile a8 *a, a8 v, morder mo);
313SANITIZER_INTERFACE_ATTRIBUTE
314a16 __tsan_atomic16_fetch_xor(volatile a16 *a, a16 v, morder mo);
315SANITIZER_INTERFACE_ATTRIBUTE
316a32 __tsan_atomic32_fetch_xor(volatile a32 *a, a32 v, morder mo);
317SANITIZER_INTERFACE_ATTRIBUTE
318a64 __tsan_atomic64_fetch_xor(volatile a64 *a, a64 v, morder mo);
319#if __TSAN_HAS_INT128
320SANITIZER_INTERFACE_ATTRIBUTE
321a128 __tsan_atomic128_fetch_xor(volatile a128 *a, a128 v, morder mo);
322#endif
323
324SANITIZER_INTERFACE_ATTRIBUTE
325a8 __tsan_atomic8_fetch_nand(volatile a8 *a, a8 v, morder mo);
326SANITIZER_INTERFACE_ATTRIBUTE
327a16 __tsan_atomic16_fetch_nand(volatile a16 *a, a16 v, morder mo);
328SANITIZER_INTERFACE_ATTRIBUTE
329a32 __tsan_atomic32_fetch_nand(volatile a32 *a, a32 v, morder mo);
330SANITIZER_INTERFACE_ATTRIBUTE
331a64 __tsan_atomic64_fetch_nand(volatile a64 *a, a64 v, morder mo);
332#if __TSAN_HAS_INT128
333SANITIZER_INTERFACE_ATTRIBUTE
334a128 __tsan_atomic128_fetch_nand(volatile a128 *a, a128 v, morder mo);
335#endif
336
337SANITIZER_INTERFACE_ATTRIBUTE
338int __tsan_atomic8_compare_exchange_strong(volatile a8 *a, a8 *c, a8 v,
339                                           morder mo, morder fmo);
340SANITIZER_INTERFACE_ATTRIBUTE
341int __tsan_atomic16_compare_exchange_strong(volatile a16 *a, a16 *c, a16 v,
342                                            morder mo, morder fmo);
343SANITIZER_INTERFACE_ATTRIBUTE
344int __tsan_atomic32_compare_exchange_strong(volatile a32 *a, a32 *c, a32 v,
345                                            morder mo, morder fmo);
346SANITIZER_INTERFACE_ATTRIBUTE
347int __tsan_atomic64_compare_exchange_strong(volatile a64 *a, a64 *c, a64 v,
348                                            morder mo, morder fmo);
349#if __TSAN_HAS_INT128
350SANITIZER_INTERFACE_ATTRIBUTE
351int __tsan_atomic128_compare_exchange_strong(volatile a128 *a, a128 *c, a128 v,
352                                             morder mo, morder fmo);
353#endif
354
355SANITIZER_INTERFACE_ATTRIBUTE
356int __tsan_atomic8_compare_exchange_weak(volatile a8 *a, a8 *c, a8 v, morder mo,
357                                         morder fmo);
358SANITIZER_INTERFACE_ATTRIBUTE
359int __tsan_atomic16_compare_exchange_weak(volatile a16 *a, a16 *c, a16 v,
360                                          morder mo, morder fmo);
361SANITIZER_INTERFACE_ATTRIBUTE
362int __tsan_atomic32_compare_exchange_weak(volatile a32 *a, a32 *c, a32 v,
363                                          morder mo, morder fmo);
364SANITIZER_INTERFACE_ATTRIBUTE
365int __tsan_atomic64_compare_exchange_weak(volatile a64 *a, a64 *c, a64 v,
366                                          morder mo, morder fmo);
367#if __TSAN_HAS_INT128
368SANITIZER_INTERFACE_ATTRIBUTE
369int __tsan_atomic128_compare_exchange_weak(volatile a128 *a, a128 *c, a128 v,
370                                           morder mo, morder fmo);
371#endif
372
373SANITIZER_INTERFACE_ATTRIBUTE
374a8 __tsan_atomic8_compare_exchange_val(volatile a8 *a, a8 c, a8 v, morder mo,
375                                       morder fmo);
376SANITIZER_INTERFACE_ATTRIBUTE
377a16 __tsan_atomic16_compare_exchange_val(volatile a16 *a, a16 c, a16 v,
378                                         morder mo, morder fmo);
379SANITIZER_INTERFACE_ATTRIBUTE
380a32 __tsan_atomic32_compare_exchange_val(volatile a32 *a, a32 c, a32 v,
381                                         morder mo, morder fmo);
382SANITIZER_INTERFACE_ATTRIBUTE
383a64 __tsan_atomic64_compare_exchange_val(volatile a64 *a, a64 c, a64 v,
384                                         morder mo, morder fmo);
385#if __TSAN_HAS_INT128
386SANITIZER_INTERFACE_ATTRIBUTE
387a128 __tsan_atomic128_compare_exchange_val(volatile a128 *a, a128 c, a128 v,
388                                           morder mo, morder fmo);
389#endif
390
391SANITIZER_INTERFACE_ATTRIBUTE
392void __tsan_atomic_thread_fence(morder mo);
393SANITIZER_INTERFACE_ATTRIBUTE
394void __tsan_atomic_signal_fence(morder mo);
395
396SANITIZER_INTERFACE_ATTRIBUTE
397void __tsan_go_atomic32_load(ThreadState *thr, uptr cpc, uptr pc, u8 *a);
398SANITIZER_INTERFACE_ATTRIBUTE
399void __tsan_go_atomic64_load(ThreadState *thr, uptr cpc, uptr pc, u8 *a);
400SANITIZER_INTERFACE_ATTRIBUTE
401void __tsan_go_atomic32_store(ThreadState *thr, uptr cpc, uptr pc, u8 *a);
402SANITIZER_INTERFACE_ATTRIBUTE
403void __tsan_go_atomic64_store(ThreadState *thr, uptr cpc, uptr pc, u8 *a);
404SANITIZER_INTERFACE_ATTRIBUTE
405void __tsan_go_atomic32_fetch_add(ThreadState *thr, uptr cpc, uptr pc, u8 *a);
406SANITIZER_INTERFACE_ATTRIBUTE
407void __tsan_go_atomic64_fetch_add(ThreadState *thr, uptr cpc, uptr pc, u8 *a);
408SANITIZER_INTERFACE_ATTRIBUTE
409void __tsan_go_atomic32_exchange(ThreadState *thr, uptr cpc, uptr pc, u8 *a);
410SANITIZER_INTERFACE_ATTRIBUTE
411void __tsan_go_atomic64_exchange(ThreadState *thr, uptr cpc, uptr pc, u8 *a);
412SANITIZER_INTERFACE_ATTRIBUTE
413void __tsan_go_atomic32_compare_exchange(ThreadState *thr, uptr cpc, uptr pc,
414                                         u8 *a);
415SANITIZER_INTERFACE_ATTRIBUTE
416void __tsan_go_atomic64_compare_exchange(ThreadState *thr, uptr cpc, uptr pc,
417                                         u8 *a);
418}  // extern "C"
419
420}  // namespace __tsan
421
422#endif  // TSAN_INTERFACE_H
423