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