1 //===-- tsan_interface.cpp ------------------------------------------------===// 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_interface_ann.h" 15 #include "tsan_rtl.h" 16 #include "sanitizer_common/sanitizer_internal_defs.h" 17 #include "sanitizer_common/sanitizer_ptrauth.h" 18 19 #define CALLERPC ((uptr)__builtin_return_address(0)) 20 21 using namespace __tsan; 22 23 void __tsan_init() { 24 cur_thread_init(); 25 Initialize(cur_thread()); 26 } 27 28 void __tsan_flush_memory() { 29 FlushShadowMemory(); 30 } 31 32 void __tsan_read16(void *addr) { 33 uptr pc = CALLERPC; 34 ThreadState *thr = cur_thread(); 35 MemoryAccess(thr, pc, (uptr)addr, 8, kAccessRead); 36 MemoryAccess(thr, pc, (uptr)addr + 8, 8, kAccessRead); 37 } 38 39 void __tsan_write16(void *addr) { 40 uptr pc = CALLERPC; 41 ThreadState *thr = cur_thread(); 42 MemoryAccess(thr, pc, (uptr)addr, 8, kAccessWrite); 43 MemoryAccess(thr, pc, (uptr)addr + 8, 8, kAccessWrite); 44 } 45 46 void __tsan_read16_pc(void *addr, void *pc) { 47 uptr pc_no_pac = STRIP_PAC_PC(pc); 48 ThreadState *thr = cur_thread(); 49 MemoryAccess(thr, pc_no_pac, (uptr)addr, 8, kAccessRead); 50 MemoryAccess(thr, pc_no_pac, (uptr)addr + 8, 8, kAccessRead); 51 } 52 53 void __tsan_write16_pc(void *addr, void *pc) { 54 uptr pc_no_pac = STRIP_PAC_PC(pc); 55 ThreadState *thr = cur_thread(); 56 MemoryAccess(thr, pc_no_pac, (uptr)addr, 8, kAccessWrite); 57 MemoryAccess(thr, pc_no_pac, (uptr)addr + 8, 8, kAccessWrite); 58 } 59 60 // __tsan_unaligned_read/write calls are emitted by compiler. 61 62 void __tsan_unaligned_read16(const void *addr) { 63 uptr pc = CALLERPC; 64 ThreadState *thr = cur_thread(); 65 UnalignedMemoryAccess(thr, pc, (uptr)addr, 8, kAccessRead); 66 UnalignedMemoryAccess(thr, pc, (uptr)addr + 8, 8, kAccessRead); 67 } 68 69 void __tsan_unaligned_write16(void *addr) { 70 uptr pc = CALLERPC; 71 ThreadState *thr = cur_thread(); 72 UnalignedMemoryAccess(thr, pc, (uptr)addr, 8, kAccessWrite); 73 UnalignedMemoryAccess(thr, pc, (uptr)addr + 8, 8, kAccessWrite); 74 } 75 76 extern "C" { 77 SANITIZER_INTERFACE_ATTRIBUTE 78 void *__tsan_get_current_fiber() { 79 return cur_thread(); 80 } 81 82 SANITIZER_INTERFACE_ATTRIBUTE 83 void *__tsan_create_fiber(unsigned flags) { 84 return FiberCreate(cur_thread(), CALLERPC, flags); 85 } 86 87 SANITIZER_INTERFACE_ATTRIBUTE 88 void __tsan_destroy_fiber(void *fiber) { 89 FiberDestroy(cur_thread(), CALLERPC, static_cast<ThreadState *>(fiber)); 90 } 91 92 SANITIZER_INTERFACE_ATTRIBUTE 93 void __tsan_switch_to_fiber(void *fiber, unsigned flags) { 94 FiberSwitch(cur_thread(), CALLERPC, static_cast<ThreadState *>(fiber), flags); 95 } 96 97 SANITIZER_INTERFACE_ATTRIBUTE 98 void __tsan_set_fiber_name(void *fiber, const char *name) { 99 ThreadSetName(static_cast<ThreadState *>(fiber), name); 100 } 101 } // extern "C" 102 103 void __tsan_acquire(void *addr) { 104 Acquire(cur_thread(), CALLERPC, (uptr)addr); 105 } 106 107 void __tsan_release(void *addr) { 108 Release(cur_thread(), CALLERPC, (uptr)addr); 109 } 110