xref: /llvm-project/compiler-rt/lib/tsan/rtl/tsan_interface.cpp (revision abb825725ebcde24011690caeeb88e582927b780)
15a3bb1a4SNico Weber //===-- tsan_interface.cpp ------------------------------------------------===//
25a3bb1a4SNico Weber //
35a3bb1a4SNico Weber // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45a3bb1a4SNico Weber // See https://llvm.org/LICENSE.txt for license information.
55a3bb1a4SNico Weber // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65a3bb1a4SNico Weber //
75a3bb1a4SNico Weber //===----------------------------------------------------------------------===//
85a3bb1a4SNico Weber //
95a3bb1a4SNico Weber // This file is a part of ThreadSanitizer (TSan), a race detector.
105a3bb1a4SNico Weber //
115a3bb1a4SNico Weber //===----------------------------------------------------------------------===//
125a3bb1a4SNico Weber 
135a3bb1a4SNico Weber #include "tsan_interface.h"
145a3bb1a4SNico Weber #include "tsan_interface_ann.h"
155a3bb1a4SNico Weber #include "tsan_rtl.h"
165a3bb1a4SNico Weber #include "sanitizer_common/sanitizer_internal_defs.h"
17e713b0ecSKuba Mracek #include "sanitizer_common/sanitizer_ptrauth.h"
185a3bb1a4SNico Weber 
195a3bb1a4SNico Weber #define CALLERPC ((uptr)__builtin_return_address(0))
205a3bb1a4SNico Weber 
21c0fa6322SVitaly Buka using namespace __tsan;
225a3bb1a4SNico Weber 
__tsan_init()23*a0ed71ffSDmitry Vyukov void __tsan_init() { Initialize(cur_thread_init()); }
245a3bb1a4SNico Weber 
__tsan_flush_memory()255a3bb1a4SNico Weber void __tsan_flush_memory() {
265a3bb1a4SNico Weber   FlushShadowMemory();
275a3bb1a4SNico Weber }
285a3bb1a4SNico Weber 
__tsan_read16_pc(void * addr,void * pc)295a3bb1a4SNico Weber void __tsan_read16_pc(void *addr, void *pc) {
30831910c5SDmitry Vyukov   uptr pc_no_pac = STRIP_PAC_PC(pc);
31831910c5SDmitry Vyukov   ThreadState *thr = cur_thread();
32831910c5SDmitry Vyukov   MemoryAccess(thr, pc_no_pac, (uptr)addr, 8, kAccessRead);
33831910c5SDmitry Vyukov   MemoryAccess(thr, pc_no_pac, (uptr)addr + 8, 8, kAccessRead);
345a3bb1a4SNico Weber }
355a3bb1a4SNico Weber 
__tsan_write16_pc(void * addr,void * pc)365a3bb1a4SNico Weber void __tsan_write16_pc(void *addr, void *pc) {
37831910c5SDmitry Vyukov   uptr pc_no_pac = STRIP_PAC_PC(pc);
38831910c5SDmitry Vyukov   ThreadState *thr = cur_thread();
39831910c5SDmitry Vyukov   MemoryAccess(thr, pc_no_pac, (uptr)addr, 8, kAccessWrite);
40831910c5SDmitry Vyukov   MemoryAccess(thr, pc_no_pac, (uptr)addr + 8, 8, kAccessWrite);
415a3bb1a4SNico Weber }
425a3bb1a4SNico Weber 
435a3bb1a4SNico Weber // __tsan_unaligned_read/write calls are emitted by compiler.
445a3bb1a4SNico Weber 
__tsan_unaligned_read16(const void * addr)455a3bb1a4SNico Weber void __tsan_unaligned_read16(const void *addr) {
46d77b476cSDmitry Vyukov   uptr pc = CALLERPC;
47d77b476cSDmitry Vyukov   ThreadState *thr = cur_thread();
48d77b476cSDmitry Vyukov   UnalignedMemoryAccess(thr, pc, (uptr)addr, 8, kAccessRead);
49d77b476cSDmitry Vyukov   UnalignedMemoryAccess(thr, pc, (uptr)addr + 8, 8, kAccessRead);
505a3bb1a4SNico Weber }
515a3bb1a4SNico Weber 
__tsan_unaligned_write16(void * addr)525a3bb1a4SNico Weber void __tsan_unaligned_write16(void *addr) {
53d77b476cSDmitry Vyukov   uptr pc = CALLERPC;
54d77b476cSDmitry Vyukov   ThreadState *thr = cur_thread();
55d77b476cSDmitry Vyukov   UnalignedMemoryAccess(thr, pc, (uptr)addr, 8, kAccessWrite);
56d77b476cSDmitry Vyukov   UnalignedMemoryAccess(thr, pc, (uptr)addr + 8, 8, kAccessWrite);
575a3bb1a4SNico Weber }
585a3bb1a4SNico Weber 
595a3bb1a4SNico Weber extern "C" {
605a3bb1a4SNico Weber SANITIZER_INTERFACE_ATTRIBUTE
__tsan_get_current_fiber()615a3bb1a4SNico Weber void *__tsan_get_current_fiber() {
625a3bb1a4SNico Weber   return cur_thread();
635a3bb1a4SNico Weber }
645a3bb1a4SNico Weber 
655a3bb1a4SNico Weber SANITIZER_INTERFACE_ATTRIBUTE
__tsan_create_fiber(unsigned flags)665a3bb1a4SNico Weber void *__tsan_create_fiber(unsigned flags) {
675a3bb1a4SNico Weber   return FiberCreate(cur_thread(), CALLERPC, flags);
685a3bb1a4SNico Weber }
695a3bb1a4SNico Weber 
705a3bb1a4SNico Weber SANITIZER_INTERFACE_ATTRIBUTE
__tsan_destroy_fiber(void * fiber)715a3bb1a4SNico Weber void __tsan_destroy_fiber(void *fiber) {
725a3bb1a4SNico Weber   FiberDestroy(cur_thread(), CALLERPC, static_cast<ThreadState *>(fiber));
735a3bb1a4SNico Weber }
745a3bb1a4SNico Weber 
755a3bb1a4SNico Weber SANITIZER_INTERFACE_ATTRIBUTE
__tsan_switch_to_fiber(void * fiber,unsigned flags)765a3bb1a4SNico Weber void __tsan_switch_to_fiber(void *fiber, unsigned flags) {
775a3bb1a4SNico Weber   FiberSwitch(cur_thread(), CALLERPC, static_cast<ThreadState *>(fiber), flags);
785a3bb1a4SNico Weber }
795a3bb1a4SNico Weber 
805a3bb1a4SNico Weber SANITIZER_INTERFACE_ATTRIBUTE
__tsan_set_fiber_name(void * fiber,const char * name)815a3bb1a4SNico Weber void __tsan_set_fiber_name(void *fiber, const char *name) {
825a3bb1a4SNico Weber   ThreadSetName(static_cast<ThreadState *>(fiber), name);
835a3bb1a4SNico Weber }
845a3bb1a4SNico Weber }  // extern "C"
855a3bb1a4SNico Weber 
__tsan_acquire(void * addr)865a3bb1a4SNico Weber void __tsan_acquire(void *addr) {
875a3bb1a4SNico Weber   Acquire(cur_thread(), CALLERPC, (uptr)addr);
885a3bb1a4SNico Weber }
895a3bb1a4SNico Weber 
__tsan_release(void * addr)905a3bb1a4SNico Weber void __tsan_release(void *addr) {
915a3bb1a4SNico Weber   Release(cur_thread(), CALLERPC, (uptr)addr);
925a3bb1a4SNico Weber }
93