1 1.1 mrg //===-- tsan_interface.inc --------------------------------------*- C++ -*-===// 2 1.1 mrg // 3 1.1 mrg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 1.1 mrg // See https://llvm.org/LICENSE.txt for license information. 5 1.1 mrg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 1.1 mrg // 7 1.1 mrg //===----------------------------------------------------------------------===// 8 1.1 mrg // 9 1.1 mrg // This file is a part of ThreadSanitizer (TSan), a race detector. 10 1.1 mrg // 11 1.1 mrg //===----------------------------------------------------------------------===// 12 1.1 mrg 13 1.1 mrg #include "sanitizer_common/sanitizer_ptrauth.h" 14 1.1 mrg #include "tsan_interface.h" 15 1.1 mrg #include "tsan_rtl.h" 16 1.1 mrg 17 1.1 mrg #define CALLERPC ((uptr)__builtin_return_address(0)) 18 1.1 mrg 19 1.1 mrg using namespace __tsan; 20 1.1 mrg 21 1.1 mrg void __tsan_read1(void *addr) { 22 1.1 mrg MemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 1, kAccessRead); 23 1.1 mrg } 24 1.1 mrg 25 1.1 mrg void __tsan_read2(void *addr) { 26 1.1 mrg MemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 2, kAccessRead); 27 1.1 mrg } 28 1.1 mrg 29 1.1 mrg void __tsan_read4(void *addr) { 30 1.1 mrg MemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 4, kAccessRead); 31 1.1 mrg } 32 1.1 mrg 33 1.1 mrg void __tsan_read8(void *addr) { 34 1.1 mrg MemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 8, kAccessRead); 35 1.1 mrg } 36 1.1 mrg 37 1.1 mrg void __tsan_write1(void *addr) { 38 1.1 mrg MemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 1, kAccessWrite); 39 1.1 mrg } 40 1.1 mrg 41 1.1 mrg void __tsan_write2(void *addr) { 42 1.1 mrg MemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 2, kAccessWrite); 43 1.1 mrg } 44 1.1 mrg 45 1.1 mrg void __tsan_write4(void *addr) { 46 1.1 mrg MemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 4, kAccessWrite); 47 1.1 mrg } 48 1.1 mrg 49 1.1 mrg void __tsan_write8(void *addr) { 50 1.1 mrg MemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 8, kAccessWrite); 51 1.1 mrg } 52 1.1 mrg 53 1.1 mrg void __tsan_read1_pc(void *addr, void *pc) { 54 1.1 mrg MemoryAccess(cur_thread(), STRIP_PAC_PC(pc), (uptr)addr, 1, kAccessRead | kAccessExternalPC); 55 1.1 mrg } 56 1.1 mrg 57 1.1 mrg void __tsan_read2_pc(void *addr, void *pc) { 58 1.1 mrg MemoryAccess(cur_thread(), STRIP_PAC_PC(pc), (uptr)addr, 2, kAccessRead | kAccessExternalPC); 59 1.1 mrg } 60 1.1 mrg 61 1.1 mrg void __tsan_read4_pc(void *addr, void *pc) { 62 1.1 mrg MemoryAccess(cur_thread(), STRIP_PAC_PC(pc), (uptr)addr, 4, kAccessRead | kAccessExternalPC); 63 1.1 mrg } 64 1.1 mrg 65 1.1 mrg void __tsan_read8_pc(void *addr, void *pc) { 66 1.1 mrg MemoryAccess(cur_thread(), STRIP_PAC_PC(pc), (uptr)addr, 8, kAccessRead | kAccessExternalPC); 67 1.1 mrg } 68 1.1 mrg 69 1.1 mrg void __tsan_write1_pc(void *addr, void *pc) { 70 1.1 mrg MemoryAccess(cur_thread(), STRIP_PAC_PC(pc), (uptr)addr, 1, kAccessWrite | kAccessExternalPC); 71 1.1 mrg } 72 1.1 mrg 73 1.1 mrg void __tsan_write2_pc(void *addr, void *pc) { 74 1.1 mrg MemoryAccess(cur_thread(), STRIP_PAC_PC(pc), (uptr)addr, 2, kAccessWrite | kAccessExternalPC); 75 1.1 mrg } 76 1.1 mrg 77 1.1 mrg void __tsan_write4_pc(void *addr, void *pc) { 78 1.1 mrg MemoryAccess(cur_thread(), STRIP_PAC_PC(pc), (uptr)addr, 4, kAccessWrite | kAccessExternalPC); 79 1.1 mrg } 80 1.1 mrg 81 1.1 mrg void __tsan_write8_pc(void *addr, void *pc) { 82 1.1 mrg MemoryAccess(cur_thread(), STRIP_PAC_PC(pc), (uptr)addr, 8, kAccessWrite | kAccessExternalPC); 83 1.1 mrg } 84 1.1 mrg 85 1.1 mrg ALWAYS_INLINE USED void __tsan_unaligned_read2(const void *addr) { 86 1.1 mrg UnalignedMemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 2, kAccessRead); 87 1.1 mrg } 88 1.1 mrg 89 1.1 mrg ALWAYS_INLINE USED void __tsan_unaligned_read4(const void *addr) { 90 1.1 mrg UnalignedMemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 4, kAccessRead); 91 1.1 mrg } 92 1.1 mrg 93 1.1 mrg ALWAYS_INLINE USED void __tsan_unaligned_read8(const void *addr) { 94 1.1 mrg UnalignedMemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 8, kAccessRead); 95 1.1 mrg } 96 1.1 mrg 97 1.1 mrg ALWAYS_INLINE USED void __tsan_unaligned_write2(void *addr) { 98 1.1 mrg UnalignedMemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 2, kAccessWrite); 99 1.1 mrg } 100 1.1 mrg 101 1.1 mrg ALWAYS_INLINE USED void __tsan_unaligned_write4(void *addr) { 102 1.1 mrg UnalignedMemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 4, kAccessWrite); 103 1.1 mrg } 104 1.1 mrg 105 1.1 mrg ALWAYS_INLINE USED void __tsan_unaligned_write8(void *addr) { 106 1.1 mrg UnalignedMemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 8, kAccessWrite); 107 1.1 mrg } 108 1.1 mrg 109 1.1 mrg extern "C" { 110 1.1 mrg // __sanitizer_unaligned_load/store are for user instrumentation. 111 1.1 mrg SANITIZER_INTERFACE_ATTRIBUTE 112 1.1 mrg u16 __sanitizer_unaligned_load16(const uu16 *addr) { 113 1.1 mrg __tsan_unaligned_read2(addr); 114 1.1 mrg return *addr; 115 1.1 mrg } 116 1.1 mrg 117 1.1 mrg SANITIZER_INTERFACE_ATTRIBUTE 118 1.1 mrg u32 __sanitizer_unaligned_load32(const uu32 *addr) { 119 1.1 mrg __tsan_unaligned_read4(addr); 120 1.1 mrg return *addr; 121 1.1 mrg } 122 1.1 mrg 123 1.1 mrg SANITIZER_INTERFACE_ATTRIBUTE 124 1.1 mrg u64 __sanitizer_unaligned_load64(const uu64 *addr) { 125 1.1 mrg __tsan_unaligned_read8(addr); 126 1.1 mrg return *addr; 127 1.1 mrg } 128 1.1 mrg 129 1.1 mrg SANITIZER_INTERFACE_ATTRIBUTE 130 1.1 mrg void __sanitizer_unaligned_store16(uu16 *addr, u16 v) { 131 1.1 mrg *addr = v; 132 1.1 mrg __tsan_unaligned_write2(addr); 133 1.1 mrg } 134 1.1 mrg 135 1.1 mrg SANITIZER_INTERFACE_ATTRIBUTE 136 1.1 mrg void __sanitizer_unaligned_store32(uu32 *addr, u32 v) { 137 1.1 mrg *addr = v; 138 1.1 mrg __tsan_unaligned_write4(addr); 139 1.1 mrg } 140 1.1 mrg 141 1.1 mrg SANITIZER_INTERFACE_ATTRIBUTE 142 1.1 mrg void __sanitizer_unaligned_store64(uu64 *addr, u64 v) { 143 1.1 mrg *addr = v; 144 1.1 mrg __tsan_unaligned_write8(addr); 145 1.1 mrg } 146 1.1 mrg } 147 1.1 mrg 148 1.1 mrg void __tsan_vptr_update(void **vptr_p, void *new_val) { 149 1.1 mrg if (*vptr_p == new_val) 150 1.1 mrg return; 151 1.1 mrg MemoryAccess(cur_thread(), CALLERPC, (uptr)vptr_p, sizeof(*vptr_p), 152 1.1 mrg kAccessWrite | kAccessVptr); 153 1.1 mrg } 154 1.1 mrg 155 1.1 mrg void __tsan_vptr_read(void **vptr_p) { 156 1.1 mrg MemoryAccess(cur_thread(), CALLERPC, (uptr)vptr_p, sizeof(*vptr_p), 157 1.1 mrg kAccessRead | kAccessVptr); 158 1.1 mrg } 159 1.1 mrg 160 1.1 mrg void __tsan_func_entry(void *pc) { FuncEntry(cur_thread(), STRIP_PAC_PC(pc)); } 161 1.1 mrg 162 1.1 mrg void __tsan_func_exit() { FuncExit(cur_thread()); } 163 1.1 mrg 164 1.1 mrg void __tsan_ignore_thread_begin() { ThreadIgnoreBegin(cur_thread(), CALLERPC); } 165 1.1 mrg 166 1.1 mrg void __tsan_ignore_thread_end() { ThreadIgnoreEnd(cur_thread()); } 167 1.1 mrg 168 1.1 mrg void __tsan_read_range(void *addr, uptr size) { 169 1.1 mrg MemoryAccessRange(cur_thread(), CALLERPC, (uptr)addr, size, false); 170 1.1 mrg } 171 1.1 mrg 172 1.1 mrg void __tsan_write_range(void *addr, uptr size) { 173 1.1 mrg MemoryAccessRange(cur_thread(), CALLERPC, (uptr)addr, size, true); 174 1.1 mrg } 175 1.1 mrg 176 1.1 mrg void __tsan_read_range_pc(void *addr, uptr size, void *pc) { 177 1.1 mrg MemoryAccessRange(cur_thread(), STRIP_PAC_PC(pc), (uptr)addr, size, false); 178 1.1 mrg } 179 1.1 mrg 180 1.1 mrg void __tsan_write_range_pc(void *addr, uptr size, void *pc) { 181 1.1 mrg MemoryAccessRange(cur_thread(), STRIP_PAC_PC(pc), (uptr)addr, size, true); 182 1.1 mrg } 183