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 typedef u16 uint16_t; 24 typedef u32 uint32_t; 25 typedef u64 uint64_t; 26 27 void __tsan_init() { 28 cur_thread_init(); 29 Initialize(cur_thread()); 30 } 31 32 void __tsan_flush_memory() { 33 FlushShadowMemory(); 34 } 35 36 void __tsan_read16(void *addr) { 37 MemoryRead(cur_thread(), CALLERPC, (uptr)addr, kSizeLog8); 38 MemoryRead(cur_thread(), CALLERPC, (uptr)addr + 8, kSizeLog8); 39 } 40 41 void __tsan_write16(void *addr) { 42 MemoryWrite(cur_thread(), CALLERPC, (uptr)addr, kSizeLog8); 43 MemoryWrite(cur_thread(), CALLERPC, (uptr)addr + 8, kSizeLog8); 44 } 45 46 void __tsan_read16_pc(void *addr, void *pc) { 47 MemoryRead(cur_thread(), STRIP_PC(pc), (uptr)addr, kSizeLog8); 48 MemoryRead(cur_thread(), STRIP_PC(pc), (uptr)addr + 8, kSizeLog8); 49 } 50 51 void __tsan_write16_pc(void *addr, void *pc) { 52 MemoryWrite(cur_thread(), STRIP_PC(pc), (uptr)addr, kSizeLog8); 53 MemoryWrite(cur_thread(), STRIP_PC(pc), (uptr)addr + 8, kSizeLog8); 54 } 55 56 // __tsan_unaligned_read/write calls are emitted by compiler. 57 58 void __tsan_unaligned_read2(const void *addr) { 59 UnalignedMemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 2, false, false); 60 } 61 62 void __tsan_unaligned_read4(const void *addr) { 63 UnalignedMemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 4, false, false); 64 } 65 66 void __tsan_unaligned_read8(const void *addr) { 67 UnalignedMemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 8, false, false); 68 } 69 70 void __tsan_unaligned_read16(const void *addr) { 71 UnalignedMemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 16, false, false); 72 } 73 74 void __tsan_unaligned_write2(void *addr) { 75 UnalignedMemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 2, true, false); 76 } 77 78 void __tsan_unaligned_write4(void *addr) { 79 UnalignedMemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 4, true, false); 80 } 81 82 void __tsan_unaligned_write8(void *addr) { 83 UnalignedMemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 8, true, false); 84 } 85 86 void __tsan_unaligned_write16(void *addr) { 87 UnalignedMemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 16, true, false); 88 } 89 90 // __sanitizer_unaligned_load/store are for user instrumentation. 91 92 extern "C" { 93 SANITIZER_INTERFACE_ATTRIBUTE 94 u16 __sanitizer_unaligned_load16(const uu16 *addr) { 95 __tsan_unaligned_read2(addr); 96 return *addr; 97 } 98 99 SANITIZER_INTERFACE_ATTRIBUTE 100 u32 __sanitizer_unaligned_load32(const uu32 *addr) { 101 __tsan_unaligned_read4(addr); 102 return *addr; 103 } 104 105 SANITIZER_INTERFACE_ATTRIBUTE 106 u64 __sanitizer_unaligned_load64(const uu64 *addr) { 107 __tsan_unaligned_read8(addr); 108 return *addr; 109 } 110 111 SANITIZER_INTERFACE_ATTRIBUTE 112 void __sanitizer_unaligned_store16(uu16 *addr, u16 v) { 113 __tsan_unaligned_write2(addr); 114 *addr = v; 115 } 116 117 SANITIZER_INTERFACE_ATTRIBUTE 118 void __sanitizer_unaligned_store32(uu32 *addr, u32 v) { 119 __tsan_unaligned_write4(addr); 120 *addr = v; 121 } 122 123 SANITIZER_INTERFACE_ATTRIBUTE 124 void __sanitizer_unaligned_store64(uu64 *addr, u64 v) { 125 __tsan_unaligned_write8(addr); 126 *addr = v; 127 } 128 129 SANITIZER_INTERFACE_ATTRIBUTE 130 void *__tsan_get_current_fiber() { 131 return cur_thread(); 132 } 133 134 SANITIZER_INTERFACE_ATTRIBUTE 135 void *__tsan_create_fiber(unsigned flags) { 136 return FiberCreate(cur_thread(), CALLERPC, flags); 137 } 138 139 SANITIZER_INTERFACE_ATTRIBUTE 140 void __tsan_destroy_fiber(void *fiber) { 141 FiberDestroy(cur_thread(), CALLERPC, static_cast<ThreadState *>(fiber)); 142 } 143 144 SANITIZER_INTERFACE_ATTRIBUTE 145 void __tsan_switch_to_fiber(void *fiber, unsigned flags) { 146 FiberSwitch(cur_thread(), CALLERPC, static_cast<ThreadState *>(fiber), flags); 147 } 148 149 SANITIZER_INTERFACE_ATTRIBUTE 150 void __tsan_set_fiber_name(void *fiber, const char *name) { 151 ThreadSetName(static_cast<ThreadState *>(fiber), name); 152 } 153 } // extern "C" 154 155 void __tsan_acquire(void *addr) { 156 Acquire(cur_thread(), CALLERPC, (uptr)addr); 157 } 158 159 void __tsan_release(void *addr) { 160 Release(cur_thread(), CALLERPC, (uptr)addr); 161 } 162