1 // Copyright 2024 The Abseil Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef ABSL_BASE_INTERNAL_POISON_H_ 16 #define ABSL_BASE_INTERNAL_POISON_H_ 17 18 #include <cstdint> 19 20 #include "absl/base/config.h" 21 22 namespace absl { 23 ABSL_NAMESPACE_BEGIN 24 namespace base_internal { 25 GetBadPointerInternal()26inline void* GetBadPointerInternal() { 27 // A likely bad pointer. Pointers are required to have high bits that are all 28 // zero or all one for certain 64-bit CPUs. This pointer value will hopefully 29 // cause a crash on dereference and also be clearly recognizable as invalid. 30 constexpr uint64_t kBadPtr = 0xBAD0BAD0BAD0BAD0; 31 auto ret = reinterpret_cast<void*>(static_cast<uintptr_t>(kBadPtr)); 32 #ifndef _MSC_VER // MSVC doesn't support inline asm with `volatile`. 33 // Try to prevent the compiler from optimizing out the undefined behavior. 34 asm volatile("" : : "r"(ret) :); // NOLINT 35 #endif 36 return ret; 37 } 38 39 void* InitializePoisonedPointerInternal(); 40 get_poisoned_pointer()41inline void* get_poisoned_pointer() { 42 #if defined(NDEBUG) && !defined(ABSL_HAVE_ADDRESS_SANITIZER) && \ 43 !defined(ABSL_HAVE_MEMORY_SANITIZER) 44 // In optimized non-sanitized builds, avoid the function-local static because 45 // of the codegen and runtime cost. 46 return GetBadPointerInternal(); 47 #else 48 // Non-optimized builds may use more robust implementation. Note that we can't 49 // use a static global because Chromium doesn't allow non-constinit globals. 50 static void* ptr = InitializePoisonedPointerInternal(); 51 return ptr; 52 #endif 53 } 54 55 } // namespace base_internal 56 ABSL_NAMESPACE_END 57 } // namespace absl 58 59 #endif // ABSL_BASE_INTERNAL_POISON_H_ 60