Path: blob/main/contrib/llvm-project/compiler-rt/lib/tsan/rtl/tsan_defs.h
35269 views
//===-- tsan_defs.h ---------------------------------------------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file is a part of ThreadSanitizer (TSan), a race detector.9//10//===----------------------------------------------------------------------===//1112#ifndef TSAN_DEFS_H13#define TSAN_DEFS_H1415#include "sanitizer_common/sanitizer_internal_defs.h"16#include "sanitizer_common/sanitizer_libc.h"17#include "sanitizer_common/sanitizer_mutex.h"18#include "ubsan/ubsan_platform.h"1920#ifndef TSAN_VECTORIZE21# define TSAN_VECTORIZE __SSE4_2__22#endif2324#if TSAN_VECTORIZE25// <emmintrin.h> transitively includes <stdlib.h>,26// and it's prohibited to include std headers into tsan runtime.27// So we do this dirty trick.28# define _MM_MALLOC_H_INCLUDED29# define __MM_MALLOC_H30# include <emmintrin.h>31# include <smmintrin.h>32# define VECTOR_ALIGNED alignas(16)33typedef __m128i m128;34#else35# define VECTOR_ALIGNED36#endif3738// Setup defaults for compile definitions.39#ifndef TSAN_NO_HISTORY40# define TSAN_NO_HISTORY 041#endif4243#ifndef TSAN_CONTAINS_UBSAN44# if CAN_SANITIZE_UB && !SANITIZER_GO45# define TSAN_CONTAINS_UBSAN 146# else47# define TSAN_CONTAINS_UBSAN 048# endif49#endif5051namespace __tsan {5253constexpr uptr kByteBits = 8;5455// Thread slot ID.56enum class Sid : u8 {};57constexpr uptr kThreadSlotCount = 256;58constexpr Sid kFreeSid = static_cast<Sid>(255);5960// Abstract time unit, vector clock element.61enum class Epoch : u16 {};62constexpr uptr kEpochBits = 14;63constexpr Epoch kEpochZero = static_cast<Epoch>(0);64constexpr Epoch kEpochOver = static_cast<Epoch>(1 << kEpochBits);65constexpr Epoch kEpochLast = static_cast<Epoch>((1 << kEpochBits) - 1);6667inline Epoch EpochInc(Epoch epoch) {68return static_cast<Epoch>(static_cast<u16>(epoch) + 1);69}7071inline bool EpochOverflow(Epoch epoch) { return epoch == kEpochOver; }7273const uptr kShadowStackSize = 64 * 1024;7475// Count of shadow values in a shadow cell.76const uptr kShadowCnt = 4;7778// That many user bytes are mapped onto a single shadow cell.79const uptr kShadowCell = 8;8081// Single shadow value.82enum class RawShadow : u32 {};83const uptr kShadowSize = sizeof(RawShadow);8485// Shadow memory is kShadowMultiplier times larger than user memory.86const uptr kShadowMultiplier = kShadowSize * kShadowCnt / kShadowCell;8788// That many user bytes are mapped onto a single meta shadow cell.89// Must be less or equal to minimal memory allocator alignment.90const uptr kMetaShadowCell = 8;9192// Size of a single meta shadow value (u32).93const uptr kMetaShadowSize = 4;9495// All addresses and PCs are assumed to be compressable to that many bits.96const uptr kCompressedAddrBits = 44;9798#if TSAN_NO_HISTORY99const bool kCollectHistory = false;100#else101const bool kCollectHistory = true;102#endif103104// The following "build consistency" machinery ensures that all source files105// are built in the same configuration. Inconsistent builds lead to106// hard to debug crashes.107#if SANITIZER_DEBUG108void build_consistency_debug();109#else110void build_consistency_release();111#endif112113static inline void USED build_consistency() {114#if SANITIZER_DEBUG115build_consistency_debug();116#else117build_consistency_release();118#endif119}120121template<typename T>122T min(T a, T b) {123return a < b ? a : b;124}125126template<typename T>127T max(T a, T b) {128return a > b ? a : b;129}130131template<typename T>132T RoundUp(T p, u64 align) {133DCHECK_EQ(align & (align - 1), 0);134return (T)(((u64)p + align - 1) & ~(align - 1));135}136137template<typename T>138T RoundDown(T p, u64 align) {139DCHECK_EQ(align & (align - 1), 0);140return (T)((u64)p & ~(align - 1));141}142143// Zeroizes high part, returns 'bits' lsb bits.144template<typename T>145T GetLsb(T v, int bits) {146return (T)((u64)v & ((1ull << bits) - 1));147}148149struct MD5Hash {150u64 hash[2];151bool operator==(const MD5Hash &other) const;152};153154MD5Hash md5_hash(const void *data, uptr size);155156struct Processor;157struct ThreadState;158class ThreadContext;159struct TidSlot;160struct Context;161struct ReportStack;162class ReportDesc;163class RegionAlloc;164struct Trace;165struct TracePart;166167typedef uptr AccessType;168169enum : AccessType {170kAccessWrite = 0,171kAccessRead = 1 << 0,172kAccessAtomic = 1 << 1,173kAccessVptr = 1 << 2, // read or write of an object virtual table pointer174kAccessFree = 1 << 3, // synthetic memory access during memory freeing175kAccessExternalPC = 1 << 4, // access PC can have kExternalPCBit set176kAccessCheckOnly = 1 << 5, // check for races, but don't store177kAccessNoRodata = 1 << 6, // don't check for .rodata marker178kAccessSlotLocked = 1 << 7, // memory access with TidSlot locked179};180181// Descriptor of user's memory block.182struct MBlock {183u64 siz : 48;184u64 tag : 16;185StackID stk;186Tid tid;187};188189COMPILER_CHECK(sizeof(MBlock) == 16);190191enum ExternalTag : uptr {192kExternalTagNone = 0,193kExternalTagSwiftModifyingAccess = 1,194kExternalTagFirstUserAvailable = 2,195kExternalTagMax = 1024,196// Don't set kExternalTagMax over 65,536, since MBlock only stores tags197// as 16-bit values, see tsan_defs.h.198};199200enum {201MutexTypeReport = MutexLastCommon,202MutexTypeSyncVar,203MutexTypeAnnotations,204MutexTypeAtExit,205MutexTypeFired,206MutexTypeRacy,207MutexTypeGlobalProc,208MutexTypeInternalAlloc,209MutexTypeTrace,210MutexTypeSlot,211MutexTypeSlots,212};213214} // namespace __tsan215216#endif // TSAN_DEFS_H217218219