13cab2bb3Spatrick //===-- tsan_interface.cpp ------------------------------------------------===//
23cab2bb3Spatrick //
33cab2bb3Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
43cab2bb3Spatrick // See https://llvm.org/LICENSE.txt for license information.
53cab2bb3Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
63cab2bb3Spatrick //
73cab2bb3Spatrick //===----------------------------------------------------------------------===//
83cab2bb3Spatrick //
93cab2bb3Spatrick // This file is a part of ThreadSanitizer (TSan), a race detector.
103cab2bb3Spatrick //
113cab2bb3Spatrick //===----------------------------------------------------------------------===//
123cab2bb3Spatrick 
133cab2bb3Spatrick #include "tsan_interface.h"
143cab2bb3Spatrick #include "tsan_interface_ann.h"
153cab2bb3Spatrick #include "tsan_rtl.h"
163cab2bb3Spatrick #include "sanitizer_common/sanitizer_internal_defs.h"
17d89ec533Spatrick #include "sanitizer_common/sanitizer_ptrauth.h"
183cab2bb3Spatrick 
193cab2bb3Spatrick #define CALLERPC ((uptr)__builtin_return_address(0))
203cab2bb3Spatrick 
213cab2bb3Spatrick using namespace __tsan;
223cab2bb3Spatrick 
__tsan_init()23*810390e3Srobert void __tsan_init() { Initialize(cur_thread_init()); }
243cab2bb3Spatrick 
__tsan_flush_memory()253cab2bb3Spatrick void __tsan_flush_memory() {
263cab2bb3Spatrick   FlushShadowMemory();
273cab2bb3Spatrick }
283cab2bb3Spatrick 
__tsan_read16_pc(void * addr,void * pc)293cab2bb3Spatrick void __tsan_read16_pc(void *addr, void *pc) {
30*810390e3Srobert   uptr pc_no_pac = STRIP_PAC_PC(pc);
31*810390e3Srobert   ThreadState *thr = cur_thread();
32*810390e3Srobert   MemoryAccess(thr, pc_no_pac, (uptr)addr, 8, kAccessRead);
33*810390e3Srobert   MemoryAccess(thr, pc_no_pac, (uptr)addr + 8, 8, kAccessRead);
343cab2bb3Spatrick }
353cab2bb3Spatrick 
__tsan_write16_pc(void * addr,void * pc)363cab2bb3Spatrick void __tsan_write16_pc(void *addr, void *pc) {
37*810390e3Srobert   uptr pc_no_pac = STRIP_PAC_PC(pc);
38*810390e3Srobert   ThreadState *thr = cur_thread();
39*810390e3Srobert   MemoryAccess(thr, pc_no_pac, (uptr)addr, 8, kAccessWrite);
40*810390e3Srobert   MemoryAccess(thr, pc_no_pac, (uptr)addr + 8, 8, kAccessWrite);
413cab2bb3Spatrick }
423cab2bb3Spatrick 
433cab2bb3Spatrick // __tsan_unaligned_read/write calls are emitted by compiler.
443cab2bb3Spatrick 
__tsan_unaligned_read16(const void * addr)453cab2bb3Spatrick void __tsan_unaligned_read16(const void *addr) {
46*810390e3Srobert   uptr pc = CALLERPC;
47*810390e3Srobert   ThreadState *thr = cur_thread();
48*810390e3Srobert   UnalignedMemoryAccess(thr, pc, (uptr)addr, 8, kAccessRead);
49*810390e3Srobert   UnalignedMemoryAccess(thr, pc, (uptr)addr + 8, 8, kAccessRead);
503cab2bb3Spatrick }
513cab2bb3Spatrick 
__tsan_unaligned_write16(void * addr)523cab2bb3Spatrick void __tsan_unaligned_write16(void *addr) {
53*810390e3Srobert   uptr pc = CALLERPC;
54*810390e3Srobert   ThreadState *thr = cur_thread();
55*810390e3Srobert   UnalignedMemoryAccess(thr, pc, (uptr)addr, 8, kAccessWrite);
56*810390e3Srobert   UnalignedMemoryAccess(thr, pc, (uptr)addr + 8, 8, kAccessWrite);
573cab2bb3Spatrick }
583cab2bb3Spatrick 
593cab2bb3Spatrick extern "C" {
603cab2bb3Spatrick SANITIZER_INTERFACE_ATTRIBUTE
__tsan_get_current_fiber()613cab2bb3Spatrick void *__tsan_get_current_fiber() {
623cab2bb3Spatrick   return cur_thread();
633cab2bb3Spatrick }
643cab2bb3Spatrick 
653cab2bb3Spatrick SANITIZER_INTERFACE_ATTRIBUTE
__tsan_create_fiber(unsigned flags)663cab2bb3Spatrick void *__tsan_create_fiber(unsigned flags) {
673cab2bb3Spatrick   return FiberCreate(cur_thread(), CALLERPC, flags);
683cab2bb3Spatrick }
693cab2bb3Spatrick 
703cab2bb3Spatrick SANITIZER_INTERFACE_ATTRIBUTE
__tsan_destroy_fiber(void * fiber)713cab2bb3Spatrick void __tsan_destroy_fiber(void *fiber) {
723cab2bb3Spatrick   FiberDestroy(cur_thread(), CALLERPC, static_cast<ThreadState *>(fiber));
733cab2bb3Spatrick }
743cab2bb3Spatrick 
753cab2bb3Spatrick SANITIZER_INTERFACE_ATTRIBUTE
__tsan_switch_to_fiber(void * fiber,unsigned flags)763cab2bb3Spatrick void __tsan_switch_to_fiber(void *fiber, unsigned flags) {
773cab2bb3Spatrick   FiberSwitch(cur_thread(), CALLERPC, static_cast<ThreadState *>(fiber), flags);
783cab2bb3Spatrick }
793cab2bb3Spatrick 
803cab2bb3Spatrick SANITIZER_INTERFACE_ATTRIBUTE
__tsan_set_fiber_name(void * fiber,const char * name)813cab2bb3Spatrick void __tsan_set_fiber_name(void *fiber, const char *name) {
823cab2bb3Spatrick   ThreadSetName(static_cast<ThreadState *>(fiber), name);
833cab2bb3Spatrick }
843cab2bb3Spatrick }  // extern "C"
853cab2bb3Spatrick 
__tsan_acquire(void * addr)863cab2bb3Spatrick void __tsan_acquire(void *addr) {
873cab2bb3Spatrick   Acquire(cur_thread(), CALLERPC, (uptr)addr);
883cab2bb3Spatrick }
893cab2bb3Spatrick 
__tsan_release(void * addr)903cab2bb3Spatrick void __tsan_release(void *addr) {
913cab2bb3Spatrick   Release(cur_thread(), CALLERPC, (uptr)addr);
923cab2bb3Spatrick }
93