123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216 |
- //===-- tsan_defs.h ---------------------------------------------*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // This file is a part of ThreadSanitizer (TSan), a race detector.
- //
- //===----------------------------------------------------------------------===//
- #ifndef TSAN_DEFS_H
- #define TSAN_DEFS_H
- #include "sanitizer_common/sanitizer_internal_defs.h"
- #include "sanitizer_common/sanitizer_libc.h"
- #include "sanitizer_common/sanitizer_mutex.h"
- #include "ubsan/ubsan_platform.h"
- #ifndef TSAN_VECTORIZE
- # define TSAN_VECTORIZE __SSE4_2__
- #endif
- #if TSAN_VECTORIZE
- // <emmintrin.h> transitively includes <stdlib.h>,
- // and it's prohibited to include std headers into tsan runtime.
- // So we do this dirty trick.
- # define _MM_MALLOC_H_INCLUDED
- # define __MM_MALLOC_H
- # include <emmintrin.h>
- # include <smmintrin.h>
- # define VECTOR_ALIGNED ALIGNED(16)
- typedef __m128i m128;
- #else
- # define VECTOR_ALIGNED
- #endif
- // Setup defaults for compile definitions.
- #ifndef TSAN_NO_HISTORY
- # define TSAN_NO_HISTORY 0
- #endif
- #ifndef TSAN_CONTAINS_UBSAN
- # if CAN_SANITIZE_UB && !SANITIZER_GO
- # define TSAN_CONTAINS_UBSAN 1
- # else
- # define TSAN_CONTAINS_UBSAN 0
- # endif
- #endif
- namespace __tsan {
- constexpr uptr kByteBits = 8;
- // Thread slot ID.
- enum class Sid : u8 {};
- constexpr uptr kThreadSlotCount = 256;
- constexpr Sid kFreeSid = static_cast<Sid>(255);
- // Abstract time unit, vector clock element.
- enum class Epoch : u16 {};
- constexpr uptr kEpochBits = 14;
- constexpr Epoch kEpochZero = static_cast<Epoch>(0);
- constexpr Epoch kEpochOver = static_cast<Epoch>(1 << kEpochBits);
- constexpr Epoch kEpochLast = static_cast<Epoch>((1 << kEpochBits) - 1);
- inline Epoch EpochInc(Epoch epoch) {
- return static_cast<Epoch>(static_cast<u16>(epoch) + 1);
- }
- inline bool EpochOverflow(Epoch epoch) { return epoch == kEpochOver; }
- const uptr kShadowStackSize = 64 * 1024;
- // Count of shadow values in a shadow cell.
- const uptr kShadowCnt = 4;
- // That many user bytes are mapped onto a single shadow cell.
- const uptr kShadowCell = 8;
- // Single shadow value.
- enum class RawShadow : u32 {};
- const uptr kShadowSize = sizeof(RawShadow);
- // Shadow memory is kShadowMultiplier times larger than user memory.
- const uptr kShadowMultiplier = kShadowSize * kShadowCnt / kShadowCell;
- // That many user bytes are mapped onto a single meta shadow cell.
- // Must be less or equal to minimal memory allocator alignment.
- const uptr kMetaShadowCell = 8;
- // Size of a single meta shadow value (u32).
- const uptr kMetaShadowSize = 4;
- // All addresses and PCs are assumed to be compressable to that many bits.
- const uptr kCompressedAddrBits = 44;
- #if TSAN_NO_HISTORY
- const bool kCollectHistory = false;
- #else
- const bool kCollectHistory = true;
- #endif
- // The following "build consistency" machinery ensures that all source files
- // are built in the same configuration. Inconsistent builds lead to
- // hard to debug crashes.
- #if SANITIZER_DEBUG
- void build_consistency_debug();
- #else
- void build_consistency_release();
- #endif
- static inline void USED build_consistency() {
- #if SANITIZER_DEBUG
- build_consistency_debug();
- #else
- build_consistency_release();
- #endif
- }
- template<typename T>
- T min(T a, T b) {
- return a < b ? a : b;
- }
- template<typename T>
- T max(T a, T b) {
- return a > b ? a : b;
- }
- template<typename T>
- T RoundUp(T p, u64 align) {
- DCHECK_EQ(align & (align - 1), 0);
- return (T)(((u64)p + align - 1) & ~(align - 1));
- }
- template<typename T>
- T RoundDown(T p, u64 align) {
- DCHECK_EQ(align & (align - 1), 0);
- return (T)((u64)p & ~(align - 1));
- }
- // Zeroizes high part, returns 'bits' lsb bits.
- template<typename T>
- T GetLsb(T v, int bits) {
- return (T)((u64)v & ((1ull << bits) - 1));
- }
- struct MD5Hash {
- u64 hash[2];
- bool operator==(const MD5Hash &other) const;
- };
- MD5Hash md5_hash(const void *data, uptr size);
- struct Processor;
- struct ThreadState;
- class ThreadContext;
- struct TidSlot;
- struct Context;
- struct ReportStack;
- class ReportDesc;
- class RegionAlloc;
- struct Trace;
- struct TracePart;
- typedef uptr AccessType;
- enum : AccessType {
- kAccessWrite = 0,
- kAccessRead = 1 << 0,
- kAccessAtomic = 1 << 1,
- kAccessVptr = 1 << 2, // read or write of an object virtual table pointer
- kAccessFree = 1 << 3, // synthetic memory access during memory freeing
- kAccessExternalPC = 1 << 4, // access PC can have kExternalPCBit set
- kAccessCheckOnly = 1 << 5, // check for races, but don't store
- kAccessNoRodata = 1 << 6, // don't check for .rodata marker
- };
- // Descriptor of user's memory block.
- struct MBlock {
- u64 siz : 48;
- u64 tag : 16;
- StackID stk;
- Tid tid;
- };
- COMPILER_CHECK(sizeof(MBlock) == 16);
- enum ExternalTag : uptr {
- kExternalTagNone = 0,
- kExternalTagSwiftModifyingAccess = 1,
- kExternalTagFirstUserAvailable = 2,
- kExternalTagMax = 1024,
- // Don't set kExternalTagMax over 65,536, since MBlock only stores tags
- // as 16-bit values, see tsan_defs.h.
- };
- enum {
- MutexTypeReport = MutexLastCommon,
- MutexTypeSyncVar,
- MutexTypeAnnotations,
- MutexTypeAtExit,
- MutexTypeFired,
- MutexTypeRacy,
- MutexTypeGlobalProc,
- MutexTypeInternalAlloc,
- MutexTypeTrace,
- MutexTypeSlot,
- MutexTypeSlots,
- };
- } // namespace __tsan
- #endif // TSAN_DEFS_H
|