xref: /freebsd/contrib/llvm-project/libcxx/include/__debug_utils/sanitizers.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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>
__annotate_double_ended_contiguous_container(const void * __first_storage,const void * __last_storage,const void * __first_old_contained,const void * __last_old_contained,const void * __first_new_contained,const void * __last_new_contained)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>
__annotate_contiguous_container(const void * __first_storage,const void * __last_storage,const void * __old_last_contained,const void * __new_last_contained)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