1 | // Copyright 2019 The Marl 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 marl_sanitizers_h |
16 | #define marl_sanitizers_h |
17 | |
18 | // Define ADDRESS_SANITIZER_ENABLED to 1 if the project was built with the |
19 | // address sanitizer enabled (-fsanitize=address). |
20 | #if defined(__SANITIZE_ADDRESS__) |
21 | #define ADDRESS_SANITIZER_ENABLED 1 |
22 | #else // defined(__SANITIZE_ADDRESS__) |
23 | #if defined(__clang__) |
24 | #if __has_feature(address_sanitizer) |
25 | #define ADDRESS_SANITIZER_ENABLED 1 |
26 | #endif // __has_feature(address_sanitizer) |
27 | #endif // defined(__clang__) |
28 | #endif // defined(__SANITIZE_ADDRESS__) |
29 | |
30 | // ADDRESS_SANITIZER_ONLY(X) resolves to X if ADDRESS_SANITIZER_ENABLED is |
31 | // defined to a non-zero value, otherwise ADDRESS_SANITIZER_ONLY() is stripped |
32 | // by the preprocessor. |
33 | #if ADDRESS_SANITIZER_ENABLED |
34 | #define ADDRESS_SANITIZER_ONLY(x) x |
35 | #else |
36 | #define ADDRESS_SANITIZER_ONLY(x) |
37 | #endif // ADDRESS_SANITIZER_ENABLED |
38 | |
39 | // Define MEMORY_SANITIZER_ENABLED to 1 if the project was built with the memory |
40 | // sanitizer enabled (-fsanitize=memory). |
41 | #if defined(__SANITIZE_MEMORY__) |
42 | #define MEMORY_SANITIZER_ENABLED 1 |
43 | #else // defined(__SANITIZE_MEMORY__) |
44 | #if defined(__clang__) |
45 | #if __has_feature(memory_sanitizer) |
46 | #define MEMORY_SANITIZER_ENABLED 1 |
47 | #endif // __has_feature(memory_sanitizer) |
48 | #endif // defined(__clang__) |
49 | #endif // defined(__SANITIZE_MEMORY__) |
50 | |
51 | // MEMORY_SANITIZER_ONLY(X) resolves to X if MEMORY_SANITIZER_ENABLED is defined |
52 | // to a non-zero value, otherwise MEMORY_SANITIZER_ONLY() is stripped by the |
53 | // preprocessor. |
54 | #if MEMORY_SANITIZER_ENABLED |
55 | #define MEMORY_SANITIZER_ONLY(x) x |
56 | #else |
57 | #define MEMORY_SANITIZER_ONLY(x) |
58 | #endif // MEMORY_SANITIZER_ENABLED |
59 | |
60 | // Define THREAD_SANITIZER_ENABLED to 1 if the project was built with the thread |
61 | // sanitizer enabled (-fsanitize=thread). |
62 | #if defined(__SANITIZE_THREAD__) |
63 | #define THREAD_SANITIZER_ENABLED 1 |
64 | #else // defined(__SANITIZE_THREAD__) |
65 | #if defined(__clang__) |
66 | #if __has_feature(thread_sanitizer) |
67 | #define THREAD_SANITIZER_ENABLED 1 |
68 | #endif // __has_feature(thread_sanitizer) |
69 | #endif // defined(__clang__) |
70 | #endif // defined(__SANITIZE_THREAD__) |
71 | |
72 | // THREAD_SANITIZER_ONLY(X) resolves to X if THREAD_SANITIZER_ENABLED is defined |
73 | // to a non-zero value, otherwise THREAD_SANITIZER_ONLY() is stripped by the |
74 | // preprocessor. |
75 | #if THREAD_SANITIZER_ENABLED |
76 | #define THREAD_SANITIZER_ONLY(x) x |
77 | #else |
78 | #define THREAD_SANITIZER_ONLY(x) |
79 | #endif // THREAD_SANITIZER_ENABLED |
80 | |
81 | // The MSAN_UNPOISON macro marks uninitialized memory as initialized for MSAN. |
82 | // It can be used to suppress false-positive MSAN errors before reading |
83 | // thread-local variables. See https://github.com/google/sanitizers/issues/1265 |
84 | #if MEMORY_SANITIZER_ENABLED |
85 | #include <sanitizer/msan_interface.h> |
86 | #define MSAN_UNPOISON(p, size) __msan_unpoison(p, size) |
87 | #else |
88 | #define MSAN_UNPOISON(p, size) |
89 | #endif |
90 | |
91 | #endif // marl_sanitizers_h |
92 | |