1 | //===-- sanitizer_internal_defs.h -------------------------------*- C++ -*-===// |
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 | // This file is shared between AddressSanitizer and ThreadSanitizer. |
10 | // It contains macro used in run-time libraries code. |
11 | //===----------------------------------------------------------------------===// |
12 | #ifndef SANITIZER_DEFS_H |
13 | #define SANITIZER_DEFS_H |
14 | |
15 | #include "sanitizer_platform.h" |
16 | #include "sanitizer_redefine_builtins.h" |
17 | |
18 | // GCC does not understand __has_feature. |
19 | #if !defined(__has_feature) |
20 | #define __has_feature(x) 0 |
21 | #endif |
22 | |
23 | #ifndef SANITIZER_DEBUG |
24 | # define SANITIZER_DEBUG 0 |
25 | #endif |
26 | |
27 | #define SANITIZER_STRINGIFY_(S) #S |
28 | #define SANITIZER_STRINGIFY(S) SANITIZER_STRINGIFY_(S) |
29 | |
30 | // Only use SANITIZER_*ATTRIBUTE* before the function return type! |
31 | #if SANITIZER_WINDOWS |
32 | #if SANITIZER_IMPORT_INTERFACE |
33 | # define SANITIZER_INTERFACE_ATTRIBUTE __declspec(dllimport) |
34 | #else |
35 | # define SANITIZER_INTERFACE_ATTRIBUTE __declspec(dllexport) |
36 | #endif |
37 | # define SANITIZER_WEAK_ATTRIBUTE |
38 | # define SANITIZER_WEAK_IMPORT |
39 | #elif SANITIZER_GO |
40 | # define SANITIZER_INTERFACE_ATTRIBUTE |
41 | # define SANITIZER_WEAK_ATTRIBUTE |
42 | # define SANITIZER_WEAK_IMPORT |
43 | #else |
44 | # define SANITIZER_INTERFACE_ATTRIBUTE __attribute__((visibility("default"))) |
45 | # define SANITIZER_WEAK_ATTRIBUTE __attribute__((weak)) |
46 | # if SANITIZER_APPLE |
47 | # define SANITIZER_WEAK_IMPORT extern "C" __attribute((weak_import)) |
48 | # else |
49 | # define SANITIZER_WEAK_IMPORT extern "C" SANITIZER_WEAK_ATTRIBUTE |
50 | # endif // SANITIZER_APPLE |
51 | #endif // SANITIZER_WINDOWS |
52 | |
53 | //--------------------------- WEAK FUNCTIONS ---------------------------------// |
54 | // When working with weak functions, to simplify the code and make it more |
55 | // portable, when possible define a default implementation using this macro: |
56 | // |
57 | // SANITIZER_INTERFACE_WEAK_DEF(<return_type>, <name>, <parameter list>) |
58 | // |
59 | // For example: |
60 | // SANITIZER_INTERFACE_WEAK_DEF(bool, compare, int a, int b) { return a > b; } |
61 | // |
62 | #if SANITIZER_WINDOWS |
63 | #include "sanitizer_win_defs.h" |
64 | # define SANITIZER_INTERFACE_WEAK_DEF(ReturnType, Name, ...) \ |
65 | WIN_WEAK_EXPORT_DEF(ReturnType, Name, __VA_ARGS__) |
66 | #else |
67 | # define SANITIZER_INTERFACE_WEAK_DEF(ReturnType, Name, ...) \ |
68 | extern "C" SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE \ |
69 | ReturnType Name(__VA_ARGS__) |
70 | #endif |
71 | |
72 | // SANITIZER_SUPPORTS_WEAK_HOOKS means that we support real weak functions that |
73 | // will evaluate to a null pointer when not defined. |
74 | #ifndef SANITIZER_SUPPORTS_WEAK_HOOKS |
75 | #if (SANITIZER_LINUX || SANITIZER_SOLARIS) && !SANITIZER_GO |
76 | # define SANITIZER_SUPPORTS_WEAK_HOOKS 1 |
77 | // Before Xcode 4.5, the Darwin linker doesn't reliably support undefined |
78 | // weak symbols. Mac OS X 10.9/Darwin 13 is the first release only supported |
79 | // by Xcode >= 4.5. |
80 | #elif SANITIZER_APPLE && \ |
81 | __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1090 && !SANITIZER_GO |
82 | # define SANITIZER_SUPPORTS_WEAK_HOOKS 1 |
83 | #else |
84 | # define SANITIZER_SUPPORTS_WEAK_HOOKS 0 |
85 | #endif |
86 | #endif // SANITIZER_SUPPORTS_WEAK_HOOKS |
87 | // For some weak hooks that will be called very often and we want to avoid the |
88 | // overhead of executing the default implementation when it is not necessary, |
89 | // we can use the flag SANITIZER_SUPPORTS_WEAK_HOOKS to only define the default |
90 | // implementation for platforms that doesn't support weak symbols. For example: |
91 | // |
92 | // #if !SANITIZER_SUPPORT_WEAK_HOOKS |
93 | // SANITIZER_INTERFACE_WEAK_DEF(bool, compare_hook, int a, int b) { |
94 | // return a > b; |
95 | // } |
96 | // #endif |
97 | // |
98 | // And then use it as: if (compare_hook) compare_hook(a, b); |
99 | //----------------------------------------------------------------------------// |
100 | |
101 | |
102 | // We can use .preinit_array section on Linux to call sanitizer initialization |
103 | // functions very early in the process startup (unless PIC macro is defined). |
104 | // |
105 | // On FreeBSD, .preinit_array functions are called with rtld_bind_lock writer |
106 | // lock held. It will lead to dead lock if unresolved PLT functions (which helds |
107 | // rtld_bind_lock reader lock) are called inside .preinit_array functions. |
108 | // |
109 | // FIXME: do we have anything like this on Mac? |
110 | #ifndef SANITIZER_CAN_USE_PREINIT_ARRAY |
111 | #if (SANITIZER_LINUX || SANITIZER_FUCHSIA || SANITIZER_NETBSD) && !defined(PIC) |
112 | #define SANITIZER_CAN_USE_PREINIT_ARRAY 1 |
113 | // Before Solaris 11.4, .preinit_array is fully supported only with GNU ld. |
114 | // FIXME: Check for those conditions. |
115 | #elif SANITIZER_SOLARIS && !defined(PIC) |
116 | # define SANITIZER_CAN_USE_PREINIT_ARRAY 1 |
117 | #else |
118 | # define SANITIZER_CAN_USE_PREINIT_ARRAY 0 |
119 | #endif |
120 | #endif // SANITIZER_CAN_USE_PREINIT_ARRAY |
121 | |
122 | // GCC does not understand __has_feature |
123 | #if !defined(__has_feature) |
124 | # define __has_feature(x) 0 |
125 | #endif |
126 | |
127 | // Older GCCs do not understand __has_attribute. |
128 | #if !defined(__has_attribute) |
129 | # define __has_attribute(x) 0 |
130 | #endif |
131 | |
132 | #if !defined(__has_cpp_attribute) |
133 | # define __has_cpp_attribute(x) 0 |
134 | #endif |
135 | |
136 | // For portability reasons we do not include stddef.h, stdint.h or any other |
137 | // system header, but we do need some basic types that are not defined |
138 | // in a portable way by the language itself. |
139 | namespace __sanitizer { |
140 | |
141 | #if defined(_WIN64) |
142 | // 64-bit Windows uses LLP64 data model. |
143 | typedef unsigned long long uptr; |
144 | typedef signed long long sptr; |
145 | #else |
146 | # if (SANITIZER_WORDSIZE == 64) || SANITIZER_APPLE || SANITIZER_WINDOWS |
147 | typedef unsigned long uptr; |
148 | typedef signed long sptr; |
149 | # else |
150 | typedef unsigned int uptr; |
151 | typedef signed int sptr; |
152 | # endif |
153 | #endif // defined(_WIN64) |
154 | #if defined(__x86_64__) |
155 | // Since x32 uses ILP32 data model in 64-bit hardware mode, we must use |
156 | // 64-bit pointer to unwind stack frame. |
157 | typedef unsigned long long uhwptr; |
158 | #else |
159 | typedef uptr uhwptr; |
160 | #endif |
161 | typedef unsigned char u8; |
162 | typedef unsigned short u16; |
163 | typedef unsigned int u32; |
164 | typedef unsigned long long u64; |
165 | typedef signed char s8; |
166 | typedef signed short s16; |
167 | typedef signed int s32; |
168 | typedef signed long long s64; |
169 | #if SANITIZER_WINDOWS |
170 | // On Windows, files are HANDLE, which is a synonim of void*. |
171 | // Use void* to avoid including <windows.h> everywhere. |
172 | typedef void* fd_t; |
173 | typedef unsigned error_t; |
174 | #else |
175 | typedef int fd_t; |
176 | typedef int error_t; |
177 | #endif |
178 | #if SANITIZER_SOLARIS && !defined(_LP64) |
179 | typedef long pid_t; |
180 | #else |
181 | typedef int pid_t; |
182 | #endif |
183 | |
184 | #if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_APPLE || \ |
185 | (SANITIZER_SOLARIS && (defined(_LP64) || _FILE_OFFSET_BITS == 64)) || \ |
186 | (SANITIZER_LINUX && !SANITIZER_GLIBC && !SANITIZER_ANDROID) || \ |
187 | (SANITIZER_LINUX && (defined(__x86_64__) || defined(__hexagon__))) |
188 | typedef u64 OFF_T; |
189 | #else |
190 | typedef uptr OFF_T; |
191 | #endif |
192 | typedef u64 OFF64_T; |
193 | |
194 | #ifdef __SIZE_TYPE__ |
195 | typedef __SIZE_TYPE__ usize; |
196 | #else |
197 | typedef uptr usize; |
198 | #endif |
199 | |
200 | typedef u64 tid_t; |
201 | |
202 | // ----------- ATTENTION ------------- |
203 | // This header should NOT include any other headers to avoid portability issues. |
204 | |
205 | // Common defs. |
206 | #define INTERFACE_ATTRIBUTE SANITIZER_INTERFACE_ATTRIBUTE |
207 | #define SANITIZER_WEAK_DEFAULT_IMPL \ |
208 | extern "C" SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE NOINLINE |
209 | #define SANITIZER_WEAK_CXX_DEFAULT_IMPL \ |
210 | extern "C++" SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE NOINLINE |
211 | |
212 | // Platform-specific defs. |
213 | #if defined(_MSC_VER) |
214 | # define ALWAYS_INLINE __forceinline |
215 | // FIXME(timurrrr): do we need this on Windows? |
216 | # define ALIAS(x) |
217 | # define ALIGNED(x) __declspec(align(x)) |
218 | # define FORMAT(f, a) |
219 | # define NOINLINE __declspec(noinline) |
220 | # define NORETURN __declspec(noreturn) |
221 | # define THREADLOCAL __declspec(thread) |
222 | # define LIKELY(x) (x) |
223 | # define UNLIKELY(x) (x) |
224 | # define PREFETCH(x) /* _mm_prefetch(x, _MM_HINT_NTA) */ (void)0 |
225 | # define WARN_UNUSED_RESULT |
226 | #else // _MSC_VER |
227 | # define ALWAYS_INLINE inline __attribute__((always_inline)) |
228 | # define ALIAS(x) __attribute__((alias(SANITIZER_STRINGIFY(x)))) |
229 | // Please only use the ALIGNED macro before the type. |
230 | // Using ALIGNED after the variable declaration is not portable! |
231 | # define ALIGNED(x) __attribute__((aligned(x))) |
232 | # define FORMAT(f, a) __attribute__((format(printf, f, a))) |
233 | # define NOINLINE __attribute__((noinline)) |
234 | # define NORETURN __attribute__((noreturn)) |
235 | # define THREADLOCAL __thread |
236 | # define LIKELY(x) __builtin_expect(!!(x), 1) |
237 | # define UNLIKELY(x) __builtin_expect(!!(x), 0) |
238 | # if defined(__i386__) || defined(__x86_64__) |
239 | // __builtin_prefetch(x) generates prefetchnt0 on x86 |
240 | # define PREFETCH(x) __asm__("prefetchnta (%0)" : : "r" (x)) |
241 | # else |
242 | # define PREFETCH(x) __builtin_prefetch(x) |
243 | # endif |
244 | # define WARN_UNUSED_RESULT __attribute__((warn_unused_result)) |
245 | #endif // _MSC_VER |
246 | |
247 | #if !defined(_MSC_VER) || defined(__clang__) |
248 | # define UNUSED __attribute__((unused)) |
249 | # define USED __attribute__((used)) |
250 | #else |
251 | # define UNUSED |
252 | # define USED |
253 | #endif |
254 | |
255 | #if !defined(_MSC_VER) || defined(__clang__) || MSC_PREREQ(1900) |
256 | # define NOEXCEPT noexcept |
257 | #else |
258 | # define NOEXCEPT throw() |
259 | #endif |
260 | |
261 | #if __has_cpp_attribute(clang::fallthrough) |
262 | # define FALLTHROUGH [[clang::fallthrough]] |
263 | #elif __has_cpp_attribute(fallthrough) |
264 | # define FALLTHROUGH [[fallthrough]] |
265 | #else |
266 | # define FALLTHROUGH |
267 | #endif |
268 | |
269 | #if __has_attribute(uninitialized) |
270 | # define UNINITIALIZED __attribute__((uninitialized)) |
271 | #else |
272 | # define UNINITIALIZED |
273 | #endif |
274 | |
275 | // Unaligned versions of basic types. |
276 | typedef ALIGNED(1) u16 uu16; |
277 | typedef ALIGNED(1) u32 uu32; |
278 | typedef ALIGNED(1) u64 uu64; |
279 | typedef ALIGNED(1) s16 us16; |
280 | typedef ALIGNED(1) s32 us32; |
281 | typedef ALIGNED(1) s64 us64; |
282 | |
283 | #if SANITIZER_WINDOWS |
284 | } // namespace __sanitizer |
285 | typedef unsigned long DWORD; |
286 | namespace __sanitizer { |
287 | typedef DWORD thread_return_t; |
288 | # define THREAD_CALLING_CONV __stdcall |
289 | #else // _WIN32 |
290 | typedef void* thread_return_t; |
291 | # define THREAD_CALLING_CONV |
292 | #endif // _WIN32 |
293 | typedef thread_return_t (THREAD_CALLING_CONV *thread_callback_t)(void* arg); |
294 | |
295 | // NOTE: Functions below must be defined in each run-time. |
296 | void NORETURN Die(); |
297 | |
298 | void NORETURN CheckFailed(const char *file, int line, const char *cond, |
299 | u64 v1, u64 v2); |
300 | |
301 | // Check macro |
302 | #define RAW_CHECK_MSG(expr, msg, ...) \ |
303 | do { \ |
304 | if (UNLIKELY(!(expr))) { \ |
305 | const char* msgs[] = {msg, __VA_ARGS__}; \ |
306 | for (const char* m : msgs) RawWrite(m); \ |
307 | Die(); \ |
308 | } \ |
309 | } while (0) |
310 | |
311 | #define RAW_CHECK(expr) RAW_CHECK_MSG(expr, #expr "\n", ) |
312 | #define RAW_CHECK_VA(expr, ...) RAW_CHECK_MSG(expr, #expr "\n", __VA_ARGS__) |
313 | |
314 | #define CHECK_IMPL(c1, op, c2) \ |
315 | do { \ |
316 | __sanitizer::u64 v1 = (__sanitizer::u64)(c1); \ |
317 | __sanitizer::u64 v2 = (__sanitizer::u64)(c2); \ |
318 | if (UNLIKELY(!(v1 op v2))) \ |
319 | __sanitizer::CheckFailed(__FILE__, __LINE__, \ |
320 | "(" #c1 ") " #op " (" #c2 ")", v1, v2); \ |
321 | } while (false) \ |
322 | /**/ |
323 | |
324 | #define CHECK(a) CHECK_IMPL((a), !=, 0) |
325 | #define CHECK_EQ(a, b) CHECK_IMPL((a), ==, (b)) |
326 | #define CHECK_NE(a, b) CHECK_IMPL((a), !=, (b)) |
327 | #define CHECK_LT(a, b) CHECK_IMPL((a), <, (b)) |
328 | #define CHECK_LE(a, b) CHECK_IMPL((a), <=, (b)) |
329 | #define CHECK_GT(a, b) CHECK_IMPL((a), >, (b)) |
330 | #define CHECK_GE(a, b) CHECK_IMPL((a), >=, (b)) |
331 | |
332 | #if SANITIZER_DEBUG |
333 | #define DCHECK(a) CHECK(a) |
334 | #define DCHECK_EQ(a, b) CHECK_EQ(a, b) |
335 | #define DCHECK_NE(a, b) CHECK_NE(a, b) |
336 | #define DCHECK_LT(a, b) CHECK_LT(a, b) |
337 | #define DCHECK_LE(a, b) CHECK_LE(a, b) |
338 | #define DCHECK_GT(a, b) CHECK_GT(a, b) |
339 | #define DCHECK_GE(a, b) CHECK_GE(a, b) |
340 | #else |
341 | #define DCHECK(a) |
342 | #define DCHECK_EQ(a, b) |
343 | #define DCHECK_NE(a, b) |
344 | #define DCHECK_LT(a, b) |
345 | #define DCHECK_LE(a, b) |
346 | #define DCHECK_GT(a, b) |
347 | #define DCHECK_GE(a, b) |
348 | #endif |
349 | |
350 | #define UNREACHABLE(msg) do { \ |
351 | CHECK(0 && msg); \ |
352 | Die(); \ |
353 | } while (0) |
354 | |
355 | #define UNIMPLEMENTED() UNREACHABLE("unimplemented") |
356 | |
357 | #define COMPILER_CHECK(pred) static_assert(pred, "") |
358 | |
359 | #define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0])) |
360 | |
361 | // Limits for integral types. We have to redefine it in case we don't |
362 | // have stdint.h (like in Visual Studio 9). |
363 | #undef __INT64_C |
364 | #undef __UINT64_C |
365 | #if SANITIZER_WORDSIZE == 64 |
366 | # define __INT64_C(c) c ## L |
367 | # define __UINT64_C(c) c ## UL |
368 | #else |
369 | # define __INT64_C(c) c ## LL |
370 | # define __UINT64_C(c) c ## ULL |
371 | #endif // SANITIZER_WORDSIZE == 64 |
372 | #undef INT32_MIN |
373 | #define INT32_MIN (-2147483647-1) |
374 | #undef INT32_MAX |
375 | #define INT32_MAX (2147483647) |
376 | #undef UINT32_MAX |
377 | #define UINT32_MAX (4294967295U) |
378 | #undef INT64_MIN |
379 | #define INT64_MIN (-__INT64_C(9223372036854775807)-1) |
380 | #undef INT64_MAX |
381 | #define INT64_MAX (__INT64_C(9223372036854775807)) |
382 | #undef UINT64_MAX |
383 | #define UINT64_MAX (__UINT64_C(18446744073709551615)) |
384 | #undef UINTPTR_MAX |
385 | #if SANITIZER_WORDSIZE == 64 |
386 | # define UINTPTR_MAX (18446744073709551615UL) |
387 | #else |
388 | # define UINTPTR_MAX (4294967295U) |
389 | #endif // SANITIZER_WORDSIZE == 64 |
390 | |
391 | enum LinkerInitialized { LINKER_INITIALIZED = 0 }; |
392 | |
393 | #if !defined(_MSC_VER) || defined(__clang__) |
394 | # define GET_CALLER_PC() \ |
395 | ((__sanitizer::uptr)__builtin_extract_return_addr( \ |
396 | __builtin_return_address(0))) |
397 | # define GET_CURRENT_FRAME() ((__sanitizer::uptr)__builtin_frame_address(0)) |
398 | inline void Trap() { |
399 | __builtin_trap(); |
400 | } |
401 | #else |
402 | extern "C" void* _ReturnAddress(void); |
403 | extern "C" void* _AddressOfReturnAddress(void); |
404 | # pragma intrinsic(_ReturnAddress) |
405 | # pragma intrinsic(_AddressOfReturnAddress) |
406 | # define GET_CALLER_PC() ((__sanitizer::uptr)_ReturnAddress()) |
407 | // CaptureStackBackTrace doesn't need to know BP on Windows. |
408 | # define GET_CURRENT_FRAME() \ |
409 | (((__sanitizer::uptr)_AddressOfReturnAddress()) + sizeof(__sanitizer::uptr)) |
410 | |
411 | extern "C" void __ud2(void); |
412 | # pragma intrinsic(__ud2) |
413 | inline void Trap() { |
414 | __ud2(); |
415 | } |
416 | #endif |
417 | |
418 | #define HANDLE_EINTR(res, f) \ |
419 | { \ |
420 | int rverrno; \ |
421 | do { \ |
422 | res = (f); \ |
423 | } while (internal_iserror(res, &rverrno) && rverrno == EINTR); \ |
424 | } |
425 | |
426 | // Forces the compiler to generate a frame pointer in the function. |
427 | #define ENABLE_FRAME_POINTER \ |
428 | do { \ |
429 | volatile __sanitizer::uptr enable_fp; \ |
430 | enable_fp = GET_CURRENT_FRAME(); \ |
431 | (void)enable_fp; \ |
432 | } while (0) |
433 | |
434 | // Internal thread identifier allocated by ThreadRegistry. |
435 | typedef u32 Tid; |
436 | constexpr Tid kInvalidTid = -1; |
437 | constexpr Tid kMainTid = 0; |
438 | |
439 | // Stack depot stack identifier. |
440 | typedef u32 StackID; |
441 | const StackID kInvalidStackID = 0; |
442 | |
443 | } // namespace __sanitizer |
444 | |
445 | namespace __asan { |
446 | using namespace __sanitizer; |
447 | } |
448 | namespace __dsan { |
449 | using namespace __sanitizer; |
450 | } |
451 | namespace __dfsan { |
452 | using namespace __sanitizer; |
453 | } |
454 | namespace __lsan { |
455 | using namespace __sanitizer; |
456 | } |
457 | namespace __msan { |
458 | using namespace __sanitizer; |
459 | } |
460 | namespace __hwasan { |
461 | using namespace __sanitizer; |
462 | } |
463 | namespace __tsan { |
464 | using namespace __sanitizer; |
465 | } |
466 | namespace __scudo { |
467 | using namespace __sanitizer; |
468 | } |
469 | namespace __ubsan { |
470 | using namespace __sanitizer; |
471 | } |
472 | namespace __xray { |
473 | using namespace __sanitizer; |
474 | } |
475 | namespace __interception { |
476 | using namespace __sanitizer; |
477 | } |
478 | namespace __hwasan { |
479 | using namespace __sanitizer; |
480 | } |
481 | namespace __memprof { |
482 | using namespace __sanitizer; |
483 | } |
484 | |
485 | #endif // SANITIZER_DEFS_H |
486 | |