1 //===-- guarded_pool_allocator_tls.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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef GWP_ASAN_GUARDED_POOL_ALLOCATOR_TLS_H_ 10 #define GWP_ASAN_GUARDED_POOL_ALLOCATOR_TLS_H_ 11 12 #include "gwp_asan/definitions.h" 13 14 #include <stdint.h> 15 16 namespace gwp_asan { 17 // Pack the thread local variables into a struct to ensure that they're in 18 // the same cache line for performance reasons. These are the most touched 19 // variables in GWP-ASan. 20 struct ThreadLocalPackedVariables { ThreadLocalPackedVariablesThreadLocalPackedVariables21 constexpr ThreadLocalPackedVariables() 22 : RandomState(0xacd979ce), NextSampleCounter(0), RecursiveGuard(false) {} 23 // Initialised to a magic constant so that an uninitialised GWP-ASan won't 24 // regenerate its sample counter for as long as possible. The xorshift32() 25 // algorithm used below results in getRandomUnsigned32(0xacd979ce) == 26 // 0xfffffffe. 27 uint32_t RandomState; 28 // Thread-local decrementing counter that indicates that a given allocation 29 // should be sampled when it reaches zero. 30 uint32_t NextSampleCounter : 31; 31 // The mask is needed to silence conversion errors. 32 static const uint32_t NextSampleCounterMask = (1U << 31) - 1; 33 // Guard against recursivity. Unwinders often contain complex behaviour that 34 // may not be safe for the allocator (i.e. the unwinder calls dlopen(), 35 // which calls malloc()). When recursive behaviour is detected, we will 36 // automatically fall back to the supporting allocator to supply the 37 // allocation. 38 bool RecursiveGuard : 1; 39 }; 40 static_assert(sizeof(ThreadLocalPackedVariables) == sizeof(uint64_t), 41 "thread local data does not fit in a uint64_t"); 42 } // namespace gwp_asan 43 44 #ifdef GWP_ASAN_PLATFORM_TLS_HEADER 45 #include GWP_ASAN_PLATFORM_TLS_HEADER 46 #else 47 namespace gwp_asan { getThreadLocals()48inline ThreadLocalPackedVariables *getThreadLocals() { 49 alignas(8) static GWP_ASAN_TLS_INITIAL_EXEC ThreadLocalPackedVariables Locals; 50 return &Locals; 51 } 52 } // namespace gwp_asan 53 #endif // GWP_ASAN_PLATFORM_TLS_HEADER 54 55 #endif // GWP_ASAN_GUARDED_POOL_ALLOCATOR_TLS_H_ 56