1*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===// 2*0fca6ea1SDimitry Andric // 3*0fca6ea1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0fca6ea1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0fca6ea1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0fca6ea1SDimitry Andric // 7*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===// 8*0fca6ea1SDimitry Andric 9*0fca6ea1SDimitry Andric #ifndef _LIBCPP___LIBCXX_DEBUG_UTILS_SANITIZERS_H 10*0fca6ea1SDimitry Andric #define _LIBCPP___LIBCXX_DEBUG_UTILS_SANITIZERS_H 11*0fca6ea1SDimitry Andric 12*0fca6ea1SDimitry Andric #include <__config> 13*0fca6ea1SDimitry Andric #include <__type_traits/integral_constant.h> 14*0fca6ea1SDimitry Andric #include <__type_traits/is_constant_evaluated.h> 15*0fca6ea1SDimitry Andric 16*0fca6ea1SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 17*0fca6ea1SDimitry Andric # pragma GCC system_header 18*0fca6ea1SDimitry Andric #endif 19*0fca6ea1SDimitry Andric 20*0fca6ea1SDimitry Andric #ifndef _LIBCPP_HAS_NO_ASAN 21*0fca6ea1SDimitry Andric 22*0fca6ea1SDimitry Andric extern "C" { 23*0fca6ea1SDimitry Andric _LIBCPP_EXPORTED_FROM_ABI void 24*0fca6ea1SDimitry Andric __sanitizer_annotate_contiguous_container(const void*, const void*, const void*, const void*); 25*0fca6ea1SDimitry Andric _LIBCPP_EXPORTED_FROM_ABI void __sanitizer_annotate_double_ended_contiguous_container( 26*0fca6ea1SDimitry Andric const void*, const void*, const void*, const void*, const void*, const void*); 27*0fca6ea1SDimitry Andric _LIBCPP_EXPORTED_FROM_ABI int 28*0fca6ea1SDimitry Andric __sanitizer_verify_double_ended_contiguous_container(const void*, const void*, const void*, const void*); 29*0fca6ea1SDimitry Andric } 30*0fca6ea1SDimitry Andric 31*0fca6ea1SDimitry Andric #endif // _LIBCPP_HAS_NO_ASAN 32*0fca6ea1SDimitry Andric 33*0fca6ea1SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD 34*0fca6ea1SDimitry Andric 35*0fca6ea1SDimitry Andric // ASan choices 36*0fca6ea1SDimitry Andric #ifndef _LIBCPP_HAS_NO_ASAN 37*0fca6ea1SDimitry Andric # define _LIBCPP_HAS_ASAN_CONTAINER_ANNOTATIONS_FOR_ALL_ALLOCATORS 1 38*0fca6ea1SDimitry Andric #endif 39*0fca6ea1SDimitry Andric 40*0fca6ea1SDimitry Andric #ifdef _LIBCPP_HAS_ASAN_CONTAINER_ANNOTATIONS_FOR_ALL_ALLOCATORS 41*0fca6ea1SDimitry Andric // __asan_annotate_container_with_allocator determines whether containers with custom allocators are annotated. This is 42*0fca6ea1SDimitry Andric // a public customization point to disable annotations if the custom allocator assumes that the memory isn't poisoned. 43*0fca6ea1SDimitry Andric // See the https://libcxx.llvm.org/UsingLibcxx.html#turning-off-asan-annotation-in-containers for more information. 44*0fca6ea1SDimitry Andric template <class _Alloc> 45*0fca6ea1SDimitry Andric struct __asan_annotate_container_with_allocator : true_type {}; 46*0fca6ea1SDimitry Andric #endif 47*0fca6ea1SDimitry Andric 48*0fca6ea1SDimitry Andric // Annotate a double-ended contiguous range. 49*0fca6ea1SDimitry Andric // - [__first_storage, __last_storage) is the allocated memory region, 50*0fca6ea1SDimitry Andric // - [__first_old_contained, __last_old_contained) is the previously allowed (unpoisoned) range, and 51*0fca6ea1SDimitry Andric // - [__first_new_contained, __last_new_contained) is the new allowed (unpoisoned) range. 52*0fca6ea1SDimitry Andric template <class _Allocator> 53*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI void __annotate_double_ended_contiguous_container( 54*0fca6ea1SDimitry Andric const void* __first_storage, 55*0fca6ea1SDimitry Andric const void* __last_storage, 56*0fca6ea1SDimitry Andric const void* __first_old_contained, 57*0fca6ea1SDimitry Andric const void* __last_old_contained, 58*0fca6ea1SDimitry Andric const void* __first_new_contained, 59*0fca6ea1SDimitry Andric const void* __last_new_contained) { 60*0fca6ea1SDimitry Andric #ifdef _LIBCPP_HAS_NO_ASAN 61*0fca6ea1SDimitry Andric (void)__first_storage; 62*0fca6ea1SDimitry Andric (void)__last_storage; 63*0fca6ea1SDimitry Andric (void)__first_old_contained; 64*0fca6ea1SDimitry Andric (void)__last_old_contained; 65*0fca6ea1SDimitry Andric (void)__first_new_contained; 66*0fca6ea1SDimitry Andric (void)__last_new_contained; 67*0fca6ea1SDimitry Andric #else 68*0fca6ea1SDimitry Andric if (__asan_annotate_container_with_allocator<_Allocator>::value && __first_storage != nullptr) 69*0fca6ea1SDimitry Andric __sanitizer_annotate_double_ended_contiguous_container( 70*0fca6ea1SDimitry Andric __first_storage, 71*0fca6ea1SDimitry Andric __last_storage, 72*0fca6ea1SDimitry Andric __first_old_contained, 73*0fca6ea1SDimitry Andric __last_old_contained, 74*0fca6ea1SDimitry Andric __first_new_contained, 75*0fca6ea1SDimitry Andric __last_new_contained); 76*0fca6ea1SDimitry Andric #endif 77*0fca6ea1SDimitry Andric } 78*0fca6ea1SDimitry Andric 79*0fca6ea1SDimitry Andric // Annotate a contiguous range. 80*0fca6ea1SDimitry Andric // [__first_storage, __last_storage) is the allocated memory region, 81*0fca6ea1SDimitry Andric // __old_last_contained is the previously last allowed (unpoisoned) element, and 82*0fca6ea1SDimitry Andric // __new_last_contained is the new last allowed (unpoisoned) element. 83*0fca6ea1SDimitry Andric template <class _Allocator> 84*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void __annotate_contiguous_container( 85*0fca6ea1SDimitry Andric const void* __first_storage, 86*0fca6ea1SDimitry Andric const void* __last_storage, 87*0fca6ea1SDimitry Andric const void* __old_last_contained, 88*0fca6ea1SDimitry Andric const void* __new_last_contained) { 89*0fca6ea1SDimitry Andric #ifdef _LIBCPP_HAS_NO_ASAN 90*0fca6ea1SDimitry Andric (void)__first_storage; 91*0fca6ea1SDimitry Andric (void)__last_storage; 92*0fca6ea1SDimitry Andric (void)__old_last_contained; 93*0fca6ea1SDimitry Andric (void)__new_last_contained; 94*0fca6ea1SDimitry Andric #else 95*0fca6ea1SDimitry Andric if (!__libcpp_is_constant_evaluated() && __asan_annotate_container_with_allocator<_Allocator>::value && 96*0fca6ea1SDimitry Andric __first_storage != nullptr) 97*0fca6ea1SDimitry Andric __sanitizer_annotate_contiguous_container( 98*0fca6ea1SDimitry Andric __first_storage, __last_storage, __old_last_contained, __new_last_contained); 99*0fca6ea1SDimitry Andric #endif 100*0fca6ea1SDimitry Andric } 101*0fca6ea1SDimitry Andric 102*0fca6ea1SDimitry Andric _LIBCPP_END_NAMESPACE_STD 103*0fca6ea1SDimitry Andric 104*0fca6ea1SDimitry Andric #endif // _LIBCPP___LIBCXX_DEBUG_UTILS_SANITIZERS_H 105