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