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