1 | //===-- sanitizer_platform.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 | // Common platform macros. |
10 | //===----------------------------------------------------------------------===// |
11 | |
12 | #ifndef SANITIZER_PLATFORM_H |
13 | #define SANITIZER_PLATFORM_H |
14 | |
15 | #if !defined(__linux__) && !defined(__FreeBSD__) && !defined(__NetBSD__) && \ |
16 | !defined(__APPLE__) && !defined(_WIN32) && !defined(__Fuchsia__) && \ |
17 | !(defined(__sun__) && defined(__svr4__)) && !defined(__HAIKU__) && \ |
18 | !defined(__wasi__) |
19 | # error "This operating system is not supported" |
20 | #endif |
21 | |
22 | // Get __GLIBC__ on a glibc platform. Exclude Android: features.h includes C |
23 | // function declarations into a .S file which doesn't compile. |
24 | // https://crbug.com/1162741 |
25 | #if __has_include(<features.h>) && !defined(__ANDROID__) |
26 | # include <features.h> |
27 | #endif |
28 | |
29 | #if defined(__linux__) |
30 | # define SANITIZER_LINUX 1 |
31 | #else |
32 | # define SANITIZER_LINUX 0 |
33 | #endif |
34 | |
35 | #if defined(__GLIBC__) |
36 | # define SANITIZER_GLIBC 1 |
37 | #else |
38 | # define SANITIZER_GLIBC 0 |
39 | #endif |
40 | |
41 | #if defined(__FreeBSD__) |
42 | # define SANITIZER_FREEBSD 1 |
43 | #else |
44 | # define SANITIZER_FREEBSD 0 |
45 | #endif |
46 | |
47 | #if defined(__NetBSD__) |
48 | # define SANITIZER_NETBSD 1 |
49 | #else |
50 | # define SANITIZER_NETBSD 0 |
51 | #endif |
52 | |
53 | #if defined(__sun__) && defined(__svr4__) |
54 | # define SANITIZER_SOLARIS 1 |
55 | #else |
56 | # define SANITIZER_SOLARIS 0 |
57 | #endif |
58 | |
59 | #if defined(__HAIKU__) |
60 | # define SANITIZER_HAIKU 1 |
61 | #else |
62 | # define SANITIZER_HAIKU 0 |
63 | #endif |
64 | |
65 | #if defined(__wasi__) |
66 | # define SANITIZER_WASI 1 |
67 | #else |
68 | # define SANITIZER_WASI 0 |
69 | #endif |
70 | |
71 | // - SANITIZER_APPLE: all Apple code |
72 | // - TARGET_OS_OSX: macOS |
73 | // - SANITIZER_IOS: devices (iOS and iOS-like) |
74 | // - SANITIZER_WATCHOS |
75 | // - SANITIZER_TVOS |
76 | // - SANITIZER_IOSSIM: simulators (iOS and iOS-like) |
77 | // - SANITIZER_DRIVERKIT |
78 | #if defined(__APPLE__) |
79 | # define SANITIZER_APPLE 1 |
80 | # include <TargetConditionals.h> |
81 | # if TARGET_OS_OSX |
82 | # define SANITIZER_OSX 1 |
83 | # else |
84 | # define SANITIZER_OSX 0 |
85 | # endif |
86 | # if TARGET_OS_IPHONE |
87 | # define SANITIZER_IOS 1 |
88 | # else |
89 | # define SANITIZER_IOS 0 |
90 | # endif |
91 | # if TARGET_OS_WATCH |
92 | # define SANITIZER_WATCHOS 1 |
93 | # else |
94 | # define SANITIZER_WATCHOS 0 |
95 | # endif |
96 | # if TARGET_OS_TV |
97 | # define SANITIZER_TVOS 1 |
98 | # else |
99 | # define SANITIZER_TVOS 0 |
100 | # endif |
101 | # if TARGET_OS_SIMULATOR |
102 | # define SANITIZER_IOSSIM 1 |
103 | # else |
104 | # define SANITIZER_IOSSIM 0 |
105 | # endif |
106 | # if defined(TARGET_OS_DRIVERKIT) && TARGET_OS_DRIVERKIT |
107 | # define SANITIZER_DRIVERKIT 1 |
108 | # else |
109 | # define SANITIZER_DRIVERKIT 0 |
110 | # endif |
111 | #else |
112 | # define SANITIZER_APPLE 0 |
113 | # define SANITIZER_OSX 0 |
114 | # define SANITIZER_IOS 0 |
115 | # define SANITIZER_WATCHOS 0 |
116 | # define SANITIZER_TVOS 0 |
117 | # define SANITIZER_IOSSIM 0 |
118 | # define SANITIZER_DRIVERKIT 0 |
119 | #endif |
120 | |
121 | #if defined(_WIN32) |
122 | # define SANITIZER_WINDOWS 1 |
123 | #else |
124 | # define SANITIZER_WINDOWS 0 |
125 | #endif |
126 | |
127 | #if defined(_WIN64) |
128 | # define SANITIZER_WINDOWS64 1 |
129 | #else |
130 | # define SANITIZER_WINDOWS64 0 |
131 | #endif |
132 | |
133 | #if defined(__ANDROID__) |
134 | # define SANITIZER_ANDROID 1 |
135 | #else |
136 | # define SANITIZER_ANDROID 0 |
137 | #endif |
138 | |
139 | #if defined(__Fuchsia__) |
140 | # define SANITIZER_FUCHSIA 1 |
141 | #else |
142 | # define SANITIZER_FUCHSIA 0 |
143 | #endif |
144 | |
145 | // Assume linux that is not glibc or android is musl libc. |
146 | #if SANITIZER_LINUX && !SANITIZER_GLIBC && !SANITIZER_ANDROID |
147 | # define SANITIZER_MUSL 1 |
148 | #else |
149 | # define SANITIZER_MUSL 0 |
150 | #endif |
151 | |
152 | #define SANITIZER_POSIX \ |
153 | (SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_APPLE || \ |
154 | SANITIZER_NETBSD || SANITIZER_SOLARIS || SANITIZER_HAIKU) |
155 | |
156 | #if __LP64__ || defined(_WIN64) |
157 | # define SANITIZER_WORDSIZE 64 |
158 | #else |
159 | # define SANITIZER_WORDSIZE 32 |
160 | #endif |
161 | |
162 | #if SANITIZER_WORDSIZE == 64 |
163 | # define FIRST_32_SECOND_64(a, b) (b) |
164 | #else |
165 | # define FIRST_32_SECOND_64(a, b) (a) |
166 | #endif |
167 | |
168 | #if defined(__x86_64__) && !defined(_LP64) |
169 | # define SANITIZER_X32 1 |
170 | #else |
171 | # define SANITIZER_X32 0 |
172 | #endif |
173 | |
174 | #if defined(__x86_64__) || defined(_M_X64) |
175 | # define SANITIZER_X64 1 |
176 | #else |
177 | # define SANITIZER_X64 0 |
178 | #endif |
179 | |
180 | #if defined(__i386__) || defined(_M_IX86) |
181 | # define SANITIZER_I386 1 |
182 | #else |
183 | # define SANITIZER_I386 0 |
184 | #endif |
185 | |
186 | #if defined(__mips__) |
187 | # define SANITIZER_MIPS 1 |
188 | # if defined(__mips64) && _MIPS_SIM == _ABI64 |
189 | # define SANITIZER_MIPS32 0 |
190 | # define SANITIZER_MIPS64 1 |
191 | # else |
192 | # define SANITIZER_MIPS32 1 |
193 | # define SANITIZER_MIPS64 0 |
194 | # endif |
195 | #else |
196 | # define SANITIZER_MIPS 0 |
197 | # define SANITIZER_MIPS32 0 |
198 | # define SANITIZER_MIPS64 0 |
199 | #endif |
200 | |
201 | #if defined(__s390__) |
202 | # define SANITIZER_S390 1 |
203 | # if defined(__s390x__) |
204 | # define SANITIZER_S390_31 0 |
205 | # define SANITIZER_S390_64 1 |
206 | # else |
207 | # define SANITIZER_S390_31 1 |
208 | # define SANITIZER_S390_64 0 |
209 | # endif |
210 | #else |
211 | # define SANITIZER_S390 0 |
212 | # define SANITIZER_S390_31 0 |
213 | # define SANITIZER_S390_64 0 |
214 | #endif |
215 | |
216 | #if defined(__sparc__) |
217 | # define SANITIZER_SPARC 1 |
218 | # if defined(__arch64__) |
219 | # define SANITIZER_SPARC32 0 |
220 | # define SANITIZER_SPARC64 1 |
221 | # else |
222 | # define SANITIZER_SPARC32 1 |
223 | # define SANITIZER_SPARC64 0 |
224 | # endif |
225 | #else |
226 | # define SANITIZER_SPARC 0 |
227 | # define SANITIZER_SPARC32 0 |
228 | # define SANITIZER_SPARC64 0 |
229 | #endif |
230 | |
231 | #if defined(__powerpc__) |
232 | # define SANITIZER_PPC 1 |
233 | # if defined(__powerpc64__) |
234 | # define SANITIZER_PPC32 0 |
235 | # define SANITIZER_PPC64 1 |
236 | // 64-bit PPC has two ABIs (v1 and v2). The old powerpc64 target is |
237 | // big-endian, and uses v1 ABI (known for its function descriptors), |
238 | // while the new powerpc64le target is little-endian and uses v2. |
239 | // In theory, you could convince gcc to compile for their evil twins |
240 | // (eg. big-endian v2), but you won't find such combinations in the wild |
241 | // (it'd require bootstrapping a whole system, which would be quite painful |
242 | // - there's no target triple for that). LLVM doesn't support them either. |
243 | # if _CALL_ELF == 2 |
244 | # define SANITIZER_PPC64V1 0 |
245 | # define SANITIZER_PPC64V2 1 |
246 | # else |
247 | # define SANITIZER_PPC64V1 1 |
248 | # define SANITIZER_PPC64V2 0 |
249 | # endif |
250 | # else |
251 | # define SANITIZER_PPC32 1 |
252 | # define SANITIZER_PPC64 0 |
253 | # define SANITIZER_PPC64V1 0 |
254 | # define SANITIZER_PPC64V2 0 |
255 | # endif |
256 | #else |
257 | # define SANITIZER_PPC 0 |
258 | # define SANITIZER_PPC32 0 |
259 | # define SANITIZER_PPC64 0 |
260 | # define SANITIZER_PPC64V1 0 |
261 | # define SANITIZER_PPC64V2 0 |
262 | #endif |
263 | |
264 | #if defined(__arm__) || defined(_M_ARM) |
265 | # define SANITIZER_ARM 1 |
266 | #else |
267 | # define SANITIZER_ARM 0 |
268 | #endif |
269 | |
270 | #if defined(__aarch64__) || defined(_M_ARM64) |
271 | # define SANITIZER_ARM64 1 |
272 | #else |
273 | # define SANITIZER_ARM64 0 |
274 | #endif |
275 | |
276 | #if SANITIZER_WINDOWS64 && SANITIZER_ARM64 |
277 | # define SANITIZER_WINDOWS_ARM64 1 |
278 | # define SANITIZER_WINDOWS_x64 0 |
279 | #elif SANITIZER_WINDOWS64 && !SANITIZER_ARM64 |
280 | # define SANITIZER_WINDOWS_ARM64 0 |
281 | # define SANITIZER_WINDOWS_x64 1 |
282 | #else |
283 | # define SANITIZER_WINDOWS_ARM64 0 |
284 | # define SANITIZER_WINDOWS_x64 0 |
285 | #endif |
286 | |
287 | #if SANITIZER_SOLARIS && SANITIZER_WORDSIZE == 32 |
288 | # define SANITIZER_SOLARIS32 1 |
289 | #else |
290 | # define SANITIZER_SOLARIS32 0 |
291 | #endif |
292 | |
293 | #if defined(__riscv) && (__riscv_xlen == 64) |
294 | # define SANITIZER_RISCV64 1 |
295 | #else |
296 | # define SANITIZER_RISCV64 0 |
297 | #endif |
298 | |
299 | #if defined(__loongarch_lp64) |
300 | # define SANITIZER_LOONGARCH64 1 |
301 | #else |
302 | # define SANITIZER_LOONGARCH64 0 |
303 | #endif |
304 | |
305 | // By default we allow to use SizeClassAllocator64 on 64-bit platform. |
306 | // But in some cases SizeClassAllocator64 does not work well and we need to |
307 | // fallback to SizeClassAllocator32. |
308 | // For such platforms build this code with -DSANITIZER_CAN_USE_ALLOCATOR64=0 or |
309 | // change the definition of SANITIZER_CAN_USE_ALLOCATOR64 here. |
310 | #ifndef SANITIZER_CAN_USE_ALLOCATOR64 |
311 | # if (SANITIZER_RISCV64 && !SANITIZER_FUCHSIA && !SANITIZER_LINUX) || \ |
312 | SANITIZER_IOS || SANITIZER_DRIVERKIT |
313 | # define SANITIZER_CAN_USE_ALLOCATOR64 0 |
314 | # elif defined(__mips64) || defined(__hexagon__) |
315 | # define SANITIZER_CAN_USE_ALLOCATOR64 0 |
316 | # else |
317 | # define SANITIZER_CAN_USE_ALLOCATOR64 (SANITIZER_WORDSIZE == 64) |
318 | # endif |
319 | #endif |
320 | |
321 | // The range of addresses which can be returned my mmap. |
322 | // FIXME: this value should be different on different platforms. Larger values |
323 | // will still work but will consume more memory for TwoLevelByteMap. |
324 | #if defined(__mips__) |
325 | # if SANITIZER_GO && defined(__mips64) |
326 | # define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 47) |
327 | # else |
328 | # define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 40) |
329 | # endif |
330 | #elif SANITIZER_RISCV64 |
331 | // FIXME: Rather than hardcoding the VMA here, we should rely on |
332 | // GetMaxUserVirtualAddress(). This will require some refactoring though since |
333 | // many places either hardcode some value or SANITIZER_MMAP_RANGE_SIZE is |
334 | // assumed to be some constant integer. |
335 | # if SANITIZER_FUCHSIA |
336 | # define SANITIZER_MMAP_RANGE_SIZE (1ULL << 38) |
337 | # else |
338 | # define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 56) |
339 | # endif |
340 | #elif defined(__aarch64__) |
341 | # if SANITIZER_APPLE |
342 | # if SANITIZER_OSX || SANITIZER_IOSSIM |
343 | # define SANITIZER_MMAP_RANGE_SIZE \ |
344 | FIRST_32_SECOND_64(1ULL << 32, 1ULL << 47) |
345 | # else |
346 | // Darwin iOS/ARM64 has a 36-bit VMA, 64GiB VM |
347 | # define SANITIZER_MMAP_RANGE_SIZE \ |
348 | FIRST_32_SECOND_64(1ULL << 32, 1ULL << 36) |
349 | # endif |
350 | # else |
351 | # define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 48) |
352 | # endif |
353 | #elif defined(__sparc__) |
354 | # define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 52) |
355 | #else |
356 | # define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 47) |
357 | #endif |
358 | |
359 | // Whether the addresses are sign-extended from the VMA range to the word. |
360 | // The SPARC64 Linux port implements this to split the VMA space into two |
361 | // non-contiguous halves with a huge hole in the middle. |
362 | #if defined(__sparc__) && SANITIZER_WORDSIZE == 64 |
363 | # define SANITIZER_SIGN_EXTENDED_ADDRESSES 1 |
364 | #else |
365 | # define SANITIZER_SIGN_EXTENDED_ADDRESSES 0 |
366 | #endif |
367 | |
368 | // udi16 syscalls can only be used when the following conditions are |
369 | // met: |
370 | // * target is one of arm32, x86-32, sparc32, sh or m68k |
371 | // * libc version is libc5, glibc-2.0, glibc-2.1 or glibc-2.2 to 2.15 |
372 | // built against > linux-2.2 kernel headers |
373 | // Since we don't want to include libc headers here, we check the |
374 | // target only. |
375 | #if defined(__arm__) || SANITIZER_X32 || defined(__sparc__) |
376 | # define SANITIZER_USES_UID16_SYSCALLS 1 |
377 | #else |
378 | # define SANITIZER_USES_UID16_SYSCALLS 0 |
379 | #endif |
380 | |
381 | #if defined(__mips__) |
382 | # define SANITIZER_POINTER_FORMAT_LENGTH FIRST_32_SECOND_64(8, 10) |
383 | #else |
384 | # define SANITIZER_POINTER_FORMAT_LENGTH FIRST_32_SECOND_64(8, 12) |
385 | #endif |
386 | |
387 | /// \macro MSC_PREREQ |
388 | /// \brief Is the compiler MSVC of at least the specified version? |
389 | /// The common \param version values to check for are: |
390 | /// * 1800: Microsoft Visual Studio 2013 / 12.0 |
391 | /// * 1900: Microsoft Visual Studio 2015 / 14.0 |
392 | #ifdef _MSC_VER |
393 | # define MSC_PREREQ(version) (_MSC_VER >= (version)) |
394 | #else |
395 | # define MSC_PREREQ(version) 0 |
396 | #endif |
397 | |
398 | #if SANITIZER_APPLE && defined(__x86_64__) |
399 | # define SANITIZER_NON_UNIQUE_TYPEINFO 0 |
400 | #else |
401 | # define SANITIZER_NON_UNIQUE_TYPEINFO 1 |
402 | #endif |
403 | |
404 | // On linux, some architectures had an ABI transition from 64-bit long double |
405 | // (ie. same as double) to 128-bit long double. On those, glibc symbols |
406 | // involving long doubles come in two versions, and we need to pass the |
407 | // correct one to dlvsym when intercepting them. |
408 | #if SANITIZER_LINUX && (SANITIZER_S390 || SANITIZER_PPC32 || SANITIZER_PPC64V1) |
409 | # define SANITIZER_NLDBL_VERSION "GLIBC_2.4" |
410 | #endif |
411 | |
412 | #if SANITIZER_GO == 0 |
413 | # define SANITIZER_GO 0 |
414 | #endif |
415 | |
416 | // On PowerPC and ARM Thumb, calling pthread_exit() causes LSan to detect leaks. |
417 | // pthread_exit() performs unwinding that leads to dlopen'ing libgcc_s.so. |
418 | // dlopen mallocs "libgcc_s.so" string which confuses LSan, it fails to realize |
419 | // that this allocation happens in dynamic linker and should be ignored. |
420 | #if SANITIZER_PPC || defined(__thumb__) |
421 | # define SANITIZER_SUPPRESS_LEAK_ON_PTHREAD_EXIT 1 |
422 | #else |
423 | # define SANITIZER_SUPPRESS_LEAK_ON_PTHREAD_EXIT 0 |
424 | #endif |
425 | |
426 | #if SANITIZER_FREEBSD || SANITIZER_APPLE || SANITIZER_NETBSD || \ |
427 | SANITIZER_SOLARIS || SANITIZER_HAIKU |
428 | # define SANITIZER_MADVISE_DONTNEED MADV_FREE |
429 | #else |
430 | # define SANITIZER_MADVISE_DONTNEED MADV_DONTNEED |
431 | #endif |
432 | |
433 | // Older gcc have issues aligning to a constexpr, and require an integer. |
434 | // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56859 among others. |
435 | #if defined(__powerpc__) || defined(__powerpc64__) |
436 | # define SANITIZER_CACHE_LINE_SIZE 128 |
437 | #else |
438 | # define SANITIZER_CACHE_LINE_SIZE 64 |
439 | #endif |
440 | |
441 | // Enable offline markup symbolizer for Fuchsia. |
442 | #if SANITIZER_FUCHSIA |
443 | # define SANITIZER_SYMBOLIZER_MARKUP 1 |
444 | #else |
445 | # define SANITIZER_SYMBOLIZER_MARKUP 0 |
446 | #endif |
447 | |
448 | // Enable ability to support sanitizer initialization that is |
449 | // compatible with the sanitizer library being loaded via |
450 | // `dlopen()`. |
451 | #if SANITIZER_APPLE |
452 | # define SANITIZER_SUPPORTS_INIT_FOR_DLOPEN 1 |
453 | #else |
454 | # define SANITIZER_SUPPORTS_INIT_FOR_DLOPEN 0 |
455 | #endif |
456 | |
457 | // SANITIZER_SUPPORTS_THREADLOCAL |
458 | // 1 - THREADLOCAL macro is supported by target |
459 | // 0 - THREADLOCAL macro is not supported by target |
460 | #ifndef __has_feature |
461 | // TODO: Support other compilers here |
462 | # define SANITIZER_SUPPORTS_THREADLOCAL 1 |
463 | #else |
464 | # if __has_feature(tls) |
465 | # define SANITIZER_SUPPORTS_THREADLOCAL 1 |
466 | # else |
467 | # define SANITIZER_SUPPORTS_THREADLOCAL 0 |
468 | # endif |
469 | #endif |
470 | |
471 | #if defined(__thumb__) && defined(__linux__) |
472 | // Workaround for |
473 | // https://lab.llvm.org/buildbot/#/builders/clang-thumbv7-full-2stage |
474 | // or |
475 | // https://lab.llvm.org/staging/#/builders/clang-thumbv7-full-2stage |
476 | // It fails *rss_limit_mb_test* without meaningful errors. |
477 | # define SANITIZER_START_BACKGROUND_THREAD_IN_ASAN_INTERNAL 1 |
478 | #else |
479 | # define SANITIZER_START_BACKGROUND_THREAD_IN_ASAN_INTERNAL 0 |
480 | #endif |
481 | |
482 | #endif // SANITIZER_PLATFORM_H |
483 | |