1353944Sdim//===-- tsan_interface.cpp ------------------------------------------------===// 2353944Sdim// 3353944Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353944Sdim// See https://llvm.org/LICENSE.txt for license information. 5353944Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6353944Sdim// 7353944Sdim//===----------------------------------------------------------------------===// 8353944Sdim// 9353944Sdim// This file is a part of ThreadSanitizer (TSan), a race detector. 10353944Sdim// 11353944Sdim//===----------------------------------------------------------------------===// 12353944Sdim 13353944Sdim#include "tsan_interface.h" 14353944Sdim#include "tsan_interface_ann.h" 15353944Sdim#include "tsan_rtl.h" 16353944Sdim#include "sanitizer_common/sanitizer_internal_defs.h" 17353944Sdim 18353944Sdim#define CALLERPC ((uptr)__builtin_return_address(0)) 19353944Sdim 20353944Sdimusing namespace __tsan; 21353944Sdim 22353944Sdimtypedef u16 uint16_t; 23353944Sdimtypedef u32 uint32_t; 24353944Sdimtypedef u64 uint64_t; 25353944Sdim 26353944Sdimvoid __tsan_init() { 27353944Sdim cur_thread_init(); 28353944Sdim Initialize(cur_thread()); 29353944Sdim} 30353944Sdim 31353944Sdimvoid __tsan_flush_memory() { 32353944Sdim FlushShadowMemory(); 33353944Sdim} 34353944Sdim 35353944Sdimvoid __tsan_read16(void *addr) { 36353944Sdim MemoryRead(cur_thread(), CALLERPC, (uptr)addr, kSizeLog8); 37353944Sdim MemoryRead(cur_thread(), CALLERPC, (uptr)addr + 8, kSizeLog8); 38353944Sdim} 39353944Sdim 40353944Sdimvoid __tsan_write16(void *addr) { 41353944Sdim MemoryWrite(cur_thread(), CALLERPC, (uptr)addr, kSizeLog8); 42353944Sdim MemoryWrite(cur_thread(), CALLERPC, (uptr)addr + 8, kSizeLog8); 43353944Sdim} 44353944Sdim 45353944Sdimvoid __tsan_read16_pc(void *addr, void *pc) { 46353944Sdim MemoryRead(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog8); 47353944Sdim MemoryRead(cur_thread(), (uptr)pc, (uptr)addr + 8, kSizeLog8); 48353944Sdim} 49353944Sdim 50353944Sdimvoid __tsan_write16_pc(void *addr, void *pc) { 51353944Sdim MemoryWrite(cur_thread(), (uptr)pc, (uptr)addr, kSizeLog8); 52353944Sdim MemoryWrite(cur_thread(), (uptr)pc, (uptr)addr + 8, kSizeLog8); 53353944Sdim} 54353944Sdim 55353944Sdim// __tsan_unaligned_read/write calls are emitted by compiler. 56353944Sdim 57353944Sdimvoid __tsan_unaligned_read2(const void *addr) { 58353944Sdim UnalignedMemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 2, false, false); 59353944Sdim} 60353944Sdim 61353944Sdimvoid __tsan_unaligned_read4(const void *addr) { 62353944Sdim UnalignedMemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 4, false, false); 63353944Sdim} 64353944Sdim 65353944Sdimvoid __tsan_unaligned_read8(const void *addr) { 66353944Sdim UnalignedMemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 8, false, false); 67353944Sdim} 68353944Sdim 69353944Sdimvoid __tsan_unaligned_read16(const void *addr) { 70353944Sdim UnalignedMemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 16, false, false); 71353944Sdim} 72353944Sdim 73353944Sdimvoid __tsan_unaligned_write2(void *addr) { 74353944Sdim UnalignedMemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 2, true, false); 75353944Sdim} 76353944Sdim 77353944Sdimvoid __tsan_unaligned_write4(void *addr) { 78353944Sdim UnalignedMemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 4, true, false); 79353944Sdim} 80353944Sdim 81353944Sdimvoid __tsan_unaligned_write8(void *addr) { 82353944Sdim UnalignedMemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 8, true, false); 83353944Sdim} 84353944Sdim 85353944Sdimvoid __tsan_unaligned_write16(void *addr) { 86353944Sdim UnalignedMemoryAccess(cur_thread(), CALLERPC, (uptr)addr, 16, true, false); 87353944Sdim} 88353944Sdim 89353944Sdim// __sanitizer_unaligned_load/store are for user instrumentation. 90353944Sdim 91353944Sdimextern "C" { 92353944SdimSANITIZER_INTERFACE_ATTRIBUTE 93353944Sdimu16 __sanitizer_unaligned_load16(const uu16 *addr) { 94353944Sdim __tsan_unaligned_read2(addr); 95353944Sdim return *addr; 96353944Sdim} 97353944Sdim 98353944SdimSANITIZER_INTERFACE_ATTRIBUTE 99353944Sdimu32 __sanitizer_unaligned_load32(const uu32 *addr) { 100353944Sdim __tsan_unaligned_read4(addr); 101353944Sdim return *addr; 102353944Sdim} 103353944Sdim 104353944SdimSANITIZER_INTERFACE_ATTRIBUTE 105353944Sdimu64 __sanitizer_unaligned_load64(const uu64 *addr) { 106353944Sdim __tsan_unaligned_read8(addr); 107353944Sdim return *addr; 108353944Sdim} 109353944Sdim 110353944SdimSANITIZER_INTERFACE_ATTRIBUTE 111353944Sdimvoid __sanitizer_unaligned_store16(uu16 *addr, u16 v) { 112353944Sdim __tsan_unaligned_write2(addr); 113353944Sdim *addr = v; 114353944Sdim} 115353944Sdim 116353944SdimSANITIZER_INTERFACE_ATTRIBUTE 117353944Sdimvoid __sanitizer_unaligned_store32(uu32 *addr, u32 v) { 118353944Sdim __tsan_unaligned_write4(addr); 119353944Sdim *addr = v; 120353944Sdim} 121353944Sdim 122353944SdimSANITIZER_INTERFACE_ATTRIBUTE 123353944Sdimvoid __sanitizer_unaligned_store64(uu64 *addr, u64 v) { 124353944Sdim __tsan_unaligned_write8(addr); 125353944Sdim *addr = v; 126353944Sdim} 127353944Sdim 128353944SdimSANITIZER_INTERFACE_ATTRIBUTE 129353944Sdimvoid *__tsan_get_current_fiber() { 130353944Sdim return cur_thread(); 131353944Sdim} 132353944Sdim 133353944SdimSANITIZER_INTERFACE_ATTRIBUTE 134353944Sdimvoid *__tsan_create_fiber(unsigned flags) { 135353944Sdim return FiberCreate(cur_thread(), CALLERPC, flags); 136353944Sdim} 137353944Sdim 138353944SdimSANITIZER_INTERFACE_ATTRIBUTE 139353944Sdimvoid __tsan_destroy_fiber(void *fiber) { 140353944Sdim FiberDestroy(cur_thread(), CALLERPC, static_cast<ThreadState *>(fiber)); 141353944Sdim} 142353944Sdim 143353944SdimSANITIZER_INTERFACE_ATTRIBUTE 144353944Sdimvoid __tsan_switch_to_fiber(void *fiber, unsigned flags) { 145353944Sdim FiberSwitch(cur_thread(), CALLERPC, static_cast<ThreadState *>(fiber), flags); 146353944Sdim} 147353944Sdim 148353944SdimSANITIZER_INTERFACE_ATTRIBUTE 149353944Sdimvoid __tsan_set_fiber_name(void *fiber, const char *name) { 150353944Sdim ThreadSetName(static_cast<ThreadState *>(fiber), name); 151353944Sdim} 152353944Sdim} // extern "C" 153353944Sdim 154353944Sdimvoid __tsan_acquire(void *addr) { 155353944Sdim Acquire(cur_thread(), CALLERPC, (uptr)addr); 156353944Sdim} 157353944Sdim 158353944Sdimvoid __tsan_release(void *addr) { 159353944Sdim Release(cur_thread(), CALLERPC, (uptr)addr); 160353944Sdim} 161