Home | History | Annotate | Line # | Download | only in tsan
      1  1.1  mrg //===-- tsan_defs.h ---------------------------------------------*- C++ -*-===//
      2  1.1  mrg //
      3  1.4  mrg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4  1.4  mrg // See https://llvm.org/LICENSE.txt for license information.
      5  1.4  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 #ifndef TSAN_DEFS_H
     14  1.1  mrg #define TSAN_DEFS_H
     15  1.1  mrg 
     16  1.1  mrg #include "sanitizer_common/sanitizer_internal_defs.h"
     17  1.1  mrg #include "sanitizer_common/sanitizer_libc.h"
     18  1.3  mrg #include "sanitizer_common/sanitizer_mutex.h"
     19  1.2  mrg #include "ubsan/ubsan_platform.h"
     20  1.1  mrg 
     21  1.3  mrg #ifndef TSAN_VECTORIZE
     22  1.3  mrg #  define TSAN_VECTORIZE __SSE4_2__
     23  1.3  mrg #endif
     24  1.3  mrg 
     25  1.3  mrg #if TSAN_VECTORIZE
     26  1.3  mrg // <emmintrin.h> transitively includes <stdlib.h>,
     27  1.3  mrg // and it's prohibited to include std headers into tsan runtime.
     28  1.3  mrg // So we do this dirty trick.
     29  1.3  mrg #  define _MM_MALLOC_H_INCLUDED
     30  1.3  mrg #  define __MM_MALLOC_H
     31  1.3  mrg #  include <emmintrin.h>
     32  1.3  mrg #  include <smmintrin.h>
     33  1.3  mrg #  define VECTOR_ALIGNED ALIGNED(16)
     34  1.3  mrg typedef __m128i m128;
     35  1.3  mrg #else
     36  1.3  mrg #  define VECTOR_ALIGNED
     37  1.3  mrg #endif
     38  1.3  mrg 
     39  1.2  mrg // Setup defaults for compile definitions.
     40  1.2  mrg #ifndef TSAN_NO_HISTORY
     41  1.2  mrg # define TSAN_NO_HISTORY 0
     42  1.2  mrg #endif
     43  1.2  mrg 
     44  1.2  mrg #ifndef TSAN_CONTAINS_UBSAN
     45  1.2  mrg # if CAN_SANITIZE_UB && !SANITIZER_GO
     46  1.2  mrg #  define TSAN_CONTAINS_UBSAN 1
     47  1.2  mrg # else
     48  1.2  mrg #  define TSAN_CONTAINS_UBSAN 0
     49  1.2  mrg # endif
     50  1.2  mrg #endif
     51  1.1  mrg 
     52  1.1  mrg namespace __tsan {
     53  1.1  mrg 
     54  1.3  mrg constexpr uptr kByteBits = 8;
     55  1.3  mrg 
     56  1.3  mrg // Thread slot ID.
     57  1.3  mrg enum class Sid : u8 {};
     58  1.3  mrg constexpr uptr kThreadSlotCount = 256;
     59  1.3  mrg constexpr Sid kFreeSid = static_cast<Sid>(255);
     60  1.3  mrg 
     61  1.3  mrg // Abstract time unit, vector clock element.
     62  1.3  mrg enum class Epoch : u16 {};
     63  1.3  mrg constexpr uptr kEpochBits = 14;
     64  1.3  mrg constexpr Epoch kEpochZero = static_cast<Epoch>(0);
     65  1.3  mrg constexpr Epoch kEpochOver = static_cast<Epoch>(1 << kEpochBits);
     66  1.5  mrg constexpr Epoch kEpochLast = static_cast<Epoch>((1 << kEpochBits) - 1);
     67  1.3  mrg 
     68  1.5  mrg inline Epoch EpochInc(Epoch epoch) {
     69  1.5  mrg   return static_cast<Epoch>(static_cast<u16>(epoch) + 1);
     70  1.5  mrg }
     71  1.2  mrg 
     72  1.5  mrg inline bool EpochOverflow(Epoch epoch) { return epoch == kEpochOver; }
     73  1.2  mrg 
     74  1.2  mrg const uptr kShadowStackSize = 64 * 1024;
     75  1.1  mrg 
     76  1.1  mrg // Count of shadow values in a shadow cell.
     77  1.1  mrg const uptr kShadowCnt = 4;
     78  1.1  mrg 
     79  1.1  mrg // That many user bytes are mapped onto a single shadow cell.
     80  1.1  mrg const uptr kShadowCell = 8;
     81  1.1  mrg 
     82  1.3  mrg // Single shadow value.
     83  1.5  mrg enum class RawShadow : u32 {};
     84  1.3  mrg const uptr kShadowSize = sizeof(RawShadow);
     85  1.1  mrg 
     86  1.1  mrg // Shadow memory is kShadowMultiplier times larger than user memory.
     87  1.1  mrg const uptr kShadowMultiplier = kShadowSize * kShadowCnt / kShadowCell;
     88  1.1  mrg 
     89  1.2  mrg // That many user bytes are mapped onto a single meta shadow cell.
     90  1.2  mrg // Must be less or equal to minimal memory allocator alignment.
     91  1.2  mrg const uptr kMetaShadowCell = 8;
     92  1.2  mrg 
     93  1.2  mrg // Size of a single meta shadow value (u32).
     94  1.2  mrg const uptr kMetaShadowSize = 4;
     95  1.2  mrg 
     96  1.3  mrg // All addresses and PCs are assumed to be compressable to that many bits.
     97  1.3  mrg const uptr kCompressedAddrBits = 44;
     98  1.3  mrg 
     99  1.2  mrg #if TSAN_NO_HISTORY
    100  1.2  mrg const bool kCollectHistory = false;
    101  1.1  mrg #else
    102  1.2  mrg const bool kCollectHistory = true;
    103  1.1  mrg #endif
    104  1.1  mrg 
    105  1.1  mrg // The following "build consistency" machinery ensures that all source files
    106  1.1  mrg // are built in the same configuration. Inconsistent builds lead to
    107  1.1  mrg // hard to debug crashes.
    108  1.2  mrg #if SANITIZER_DEBUG
    109  1.1  mrg void build_consistency_debug();
    110  1.1  mrg #else
    111  1.1  mrg void build_consistency_release();
    112  1.1  mrg #endif
    113  1.1  mrg 
    114  1.1  mrg static inline void USED build_consistency() {
    115  1.2  mrg #if SANITIZER_DEBUG
    116  1.1  mrg   build_consistency_debug();
    117  1.1  mrg #else
    118  1.1  mrg   build_consistency_release();
    119  1.1  mrg #endif
    120  1.1  mrg }
    121  1.1  mrg 
    122  1.1  mrg template<typename T>
    123  1.1  mrg T min(T a, T b) {
    124  1.1  mrg   return a < b ? a : b;
    125  1.1  mrg }
    126  1.1  mrg 
    127  1.1  mrg template<typename T>
    128  1.1  mrg T max(T a, T b) {
    129  1.1  mrg   return a > b ? a : b;
    130  1.1  mrg }
    131  1.1  mrg 
    132  1.1  mrg template<typename T>
    133  1.1  mrg T RoundUp(T p, u64 align) {
    134  1.1  mrg   DCHECK_EQ(align & (align - 1), 0);
    135  1.1  mrg   return (T)(((u64)p + align - 1) & ~(align - 1));
    136  1.1  mrg }
    137  1.1  mrg 
    138  1.1  mrg template<typename T>
    139  1.1  mrg T RoundDown(T p, u64 align) {
    140  1.1  mrg   DCHECK_EQ(align & (align - 1), 0);
    141  1.1  mrg   return (T)((u64)p & ~(align - 1));
    142  1.1  mrg }
    143  1.1  mrg 
    144  1.1  mrg // Zeroizes high part, returns 'bits' lsb bits.
    145  1.1  mrg template<typename T>
    146  1.1  mrg T GetLsb(T v, int bits) {
    147  1.1  mrg   return (T)((u64)v & ((1ull << bits) - 1));
    148  1.1  mrg }
    149  1.1  mrg 
    150  1.1  mrg struct MD5Hash {
    151  1.1  mrg   u64 hash[2];
    152  1.1  mrg   bool operator==(const MD5Hash &other) const;
    153  1.1  mrg };
    154  1.1  mrg 
    155  1.1  mrg MD5Hash md5_hash(const void *data, uptr size);
    156  1.1  mrg 
    157  1.2  mrg struct Processor;
    158  1.1  mrg struct ThreadState;
    159  1.2  mrg class ThreadContext;
    160  1.5  mrg struct TidSlot;
    161  1.1  mrg struct Context;
    162  1.1  mrg struct ReportStack;
    163  1.1  mrg class ReportDesc;
    164  1.1  mrg class RegionAlloc;
    165  1.5  mrg struct Trace;
    166  1.5  mrg struct TracePart;
    167  1.2  mrg 
    168  1.3  mrg typedef uptr AccessType;
    169  1.3  mrg 
    170  1.3  mrg enum : AccessType {
    171  1.3  mrg   kAccessWrite = 0,
    172  1.3  mrg   kAccessRead = 1 << 0,
    173  1.3  mrg   kAccessAtomic = 1 << 1,
    174  1.3  mrg   kAccessVptr = 1 << 2,  // read or write of an object virtual table pointer
    175  1.3  mrg   kAccessFree = 1 << 3,  // synthetic memory access during memory freeing
    176  1.3  mrg   kAccessExternalPC = 1 << 4,  // access PC can have kExternalPCBit set
    177  1.5  mrg   kAccessCheckOnly = 1 << 5,   // check for races, but don't store
    178  1.5  mrg   kAccessNoRodata = 1 << 6,    // don't check for .rodata marker
    179  1.5  mrg   kAccessSlotLocked = 1 << 7,  // memory access with TidSlot locked
    180  1.3  mrg };
    181  1.3  mrg 
    182  1.2  mrg // Descriptor of user's memory block.
    183  1.2  mrg struct MBlock {
    184  1.2  mrg   u64  siz : 48;
    185  1.2  mrg   u64  tag : 16;
    186  1.3  mrg   StackID stk;
    187  1.3  mrg   Tid tid;
    188  1.2  mrg };
    189  1.2  mrg 
    190  1.2  mrg COMPILER_CHECK(sizeof(MBlock) == 16);
    191  1.2  mrg 
    192  1.2  mrg enum ExternalTag : uptr {
    193  1.2  mrg   kExternalTagNone = 0,
    194  1.2  mrg   kExternalTagSwiftModifyingAccess = 1,
    195  1.2  mrg   kExternalTagFirstUserAvailable = 2,
    196  1.2  mrg   kExternalTagMax = 1024,
    197  1.2  mrg   // Don't set kExternalTagMax over 65,536, since MBlock only stores tags
    198  1.2  mrg   // as 16-bit values, see tsan_defs.h.
    199  1.2  mrg };
    200  1.1  mrg 
    201  1.5  mrg enum {
    202  1.5  mrg   MutexTypeReport = MutexLastCommon,
    203  1.3  mrg   MutexTypeSyncVar,
    204  1.3  mrg   MutexTypeAnnotations,
    205  1.3  mrg   MutexTypeAtExit,
    206  1.3  mrg   MutexTypeFired,
    207  1.3  mrg   MutexTypeRacy,
    208  1.3  mrg   MutexTypeGlobalProc,
    209  1.5  mrg   MutexTypeInternalAlloc,
    210  1.5  mrg   MutexTypeTrace,
    211  1.5  mrg   MutexTypeSlot,
    212  1.5  mrg   MutexTypeSlots,
    213  1.3  mrg };
    214  1.3  mrg 
    215  1.1  mrg }  // namespace __tsan
    216  1.1  mrg 
    217  1.1  mrg #endif  // TSAN_DEFS_H
    218