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