brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.4 KiB · 270d441 Raw
218 lines · c
1//===-- tsan_defs.h ---------------------------------------------*- 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-exception6//7//===----------------------------------------------------------------------===//8//9// This file is a part of ThreadSanitizer (TSan), a race detector.10//11//===----------------------------------------------------------------------===//12 13#ifndef TSAN_DEFS_H14#define TSAN_DEFS_H15 16#include "sanitizer_common/sanitizer_internal_defs.h"17#include "sanitizer_common/sanitizer_libc.h"18#include "sanitizer_common/sanitizer_mutex.h"19#include "ubsan/ubsan_platform.h"20 21#ifndef TSAN_VECTORIZE22#  define TSAN_VECTORIZE __SSE4_2__23#endif24 25#if TSAN_VECTORIZE26// <emmintrin.h> transitively includes <stdlib.h>,27// and it's prohibited to include std headers into tsan runtime.28// So we do this dirty trick.29#  define _MM_MALLOC_H_INCLUDED30#  define __MM_MALLOC_H31#  include <emmintrin.h>32#  include <smmintrin.h>33#  define VECTOR_ALIGNED alignas(16)34typedef __m128i m128;35#else36#  define VECTOR_ALIGNED37#endif38 39// Setup defaults for compile definitions.40#ifndef TSAN_NO_HISTORY41# define TSAN_NO_HISTORY 042#endif43 44#ifndef TSAN_CONTAINS_UBSAN45# if CAN_SANITIZE_UB && !SANITIZER_GO46#  define TSAN_CONTAINS_UBSAN 147# else48#  define TSAN_CONTAINS_UBSAN 049# endif50#endif51 52namespace __tsan {53 54constexpr uptr kByteBits = 8;55 56// Thread slot ID.57enum class Sid : u8 {};58constexpr uptr kThreadSlotCount = 256;59constexpr Sid kFreeSid = static_cast<Sid>(255);60 61// Abstract time unit, vector clock element.62enum class Epoch : u16 {};63constexpr uptr kEpochBits = 14;64constexpr Epoch kEpochZero = static_cast<Epoch>(0);65constexpr Epoch kEpochOver = static_cast<Epoch>(1 << kEpochBits);66constexpr Epoch kEpochLast = static_cast<Epoch>((1 << kEpochBits) - 1);67 68inline Epoch EpochInc(Epoch epoch) {69  return static_cast<Epoch>(static_cast<u16>(epoch) + 1);70}71 72inline bool EpochOverflow(Epoch epoch) { return epoch == kEpochOver; }73 74const uptr kShadowStackSize = 64 * 1024;75 76// Count of shadow values in a shadow cell.77const uptr kShadowCnt = 4;78 79// That many user bytes are mapped onto a single shadow cell.80const uptr kShadowCell = 8;81 82// Single shadow value.83enum class RawShadow : u32 {};84const uptr kShadowSize = sizeof(RawShadow);85 86// Shadow memory is kShadowMultiplier times larger than user memory.87const uptr kShadowMultiplier = kShadowSize * kShadowCnt / kShadowCell;88 89// That many user bytes are mapped onto a single meta shadow cell.90// Must be less or equal to minimal memory allocator alignment.91const uptr kMetaShadowCell = 8;92 93// Size of a single meta shadow value (u32).94const uptr kMetaShadowSize = 4;95 96// All addresses and PCs are assumed to be compressable to that many bits.97const uptr kCompressedAddrBits = 44;98 99#if TSAN_NO_HISTORY100const bool kCollectHistory = false;101#else102const bool kCollectHistory = true;103#endif104 105// The following "build consistency" machinery ensures that all source files106// are built in the same configuration. Inconsistent builds lead to107// hard to debug crashes.108#if SANITIZER_DEBUG109void build_consistency_debug();110#else111void build_consistency_release();112#endif113 114static inline void USED build_consistency() {115#if SANITIZER_DEBUG116  build_consistency_debug();117#else118  build_consistency_release();119#endif120}121 122template<typename T>123T min(T a, T b) {124  return a < b ? a : b;125}126 127template<typename T>128T max(T a, T b) {129  return a > b ? a : b;130}131 132template<typename T>133T RoundUp(T p, u64 align) {134  DCHECK_EQ(align & (align - 1), 0);135  return (T)(((u64)p + align - 1) & ~(align - 1));136}137 138template<typename T>139T RoundDown(T p, u64 align) {140  DCHECK_EQ(align & (align - 1), 0);141  return (T)((u64)p & ~(align - 1));142}143 144// Zeroizes high part, returns 'bits' lsb bits.145template<typename T>146T GetLsb(T v, int bits) {147  return (T)((u64)v & ((1ull << bits) - 1));148}149 150struct MD5Hash {151  u64 hash[2];152  bool operator==(const MD5Hash &other) const;153};154 155MD5Hash md5_hash(const void *data, uptr size);156 157struct Processor;158struct ThreadState;159class ThreadContext;160struct TidSlot;161struct Context;162struct ReportStack;163class ReportDesc;164class RegionAlloc;165struct Trace;166struct TracePart;167 168typedef uptr AccessType;169 170enum : AccessType {171  kAccessWrite = 0,172  kAccessRead = 1 << 0,173  kAccessAtomic = 1 << 1,174  kAccessVptr = 1 << 2,  // read or write of an object virtual table pointer175  kAccessFree = 1 << 3,  // synthetic memory access during memory freeing176  kAccessExternalPC = 1 << 4,  // access PC can have kExternalPCBit set177  kAccessCheckOnly = 1 << 5,   // check for races, but don't store178  kAccessNoRodata = 1 << 6,    // don't check for .rodata marker179  kAccessSlotLocked = 1 << 7,  // memory access with TidSlot locked180};181 182// Descriptor of user's memory block.183struct MBlock {184  u64  siz : 48;185  u64  tag : 16;186  StackID stk;187  Tid tid;188};189 190COMPILER_CHECK(sizeof(MBlock) == 16);191 192enum ExternalTag : uptr {193  kExternalTagNone = 0,194  kExternalTagSwiftModifyingAccess = 1,195  kExternalTagFirstUserAvailable = 2,196  kExternalTagMax = 1024,197  // Don't set kExternalTagMax over 65,536, since MBlock only stores tags198  // as 16-bit values, see tsan_defs.h.199};200 201enum {202  MutexTypeReport = MutexLastCommon,203  MutexTypeSyncVar,204  MutexTypeAnnotations,205  MutexTypeAtExit,206  MutexTypeFired,207  MutexTypeRacy,208  MutexTypeGlobalProc,209  MutexTypeInternalAlloc,210  MutexTypeTrace,211  MutexTypeSlot,212  MutexTypeSlots,213};214 215}  // namespace __tsan216 217#endif  // TSAN_DEFS_H218