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