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