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#if SANITIZER_AMDGPU || SANITIZER_NVPTX || SANITIZER_SPIRV
337# define SANITIZER_GPU 1
338#else
339# define SANITIZER_GPU 0
340#endif
341
342// By default we allow to use SizeClassAllocator64 on 64-bit platform.
343// But in some cases SizeClassAllocator64 does not work well and we need to
344// fallback to SizeClassAllocator32.
345// For such platforms build this code with -DSANITIZER_CAN_USE_ALLOCATOR64=0 or
346// change the definition of SANITIZER_CAN_USE_ALLOCATOR64 here.
347#ifndef SANITIZER_CAN_USE_ALLOCATOR64
348# if (SANITIZER_RISCV64 && !SANITIZER_FUCHSIA && !SANITIZER_LINUX) || \
349 SANITIZER_IOS || SANITIZER_DRIVERKIT
350# define SANITIZER_CAN_USE_ALLOCATOR64 0
351# elif defined(__mips64) || defined(__hexagon__)
352# define SANITIZER_CAN_USE_ALLOCATOR64 0
353# else
354# define SANITIZER_CAN_USE_ALLOCATOR64 (SANITIZER_WORDSIZE == 64)
355# endif
356#endif
357
358// The first address that can be returned by mmap.
359#if SANITIZER_AIX && SANITIZER_WORDSIZE == 64
360# define SANITIZER_MMAP_BEGIN 0x0a00'0000'0000'0000ULL
361#else
362# define SANITIZER_MMAP_BEGIN 0
363#endif
364
365// The range of addresses which can be returned my mmap.
366// FIXME: this value should be different on different platforms. Larger values
367// will still work but will consume more memory for TwoLevelByteMap.
368#if defined(__mips__)
369# if SANITIZER_GO && defined(__mips64)
370# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 47)
371# else
372# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 40)
373# endif
374#elif SANITIZER_RISCV64
375// FIXME: Rather than hardcoding the VMA here, we should rely on
376// GetMaxUserVirtualAddress(). This will require some refactoring though since
377// many places either hardcode some value or SANITIZER_MMAP_RANGE_SIZE is
378// assumed to be some constant integer.
379# if SANITIZER_FUCHSIA
380# define SANITIZER_MMAP_RANGE_SIZE (1ULL << 38)
381# else
382# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 56)
383# endif
384#elif defined(__aarch64__)
385# if SANITIZER_APPLE
386# if SANITIZER_OSX || SANITIZER_IOSSIM
387# define SANITIZER_MMAP_RANGE_SIZE \
388 FIRST_32_SECOND_64(1ULL << 32, 1ULL << 47)
389# else
390// Darwin iOS/ARM64 has a 36-bit VMA, 64GiB VM
391# define SANITIZER_MMAP_RANGE_SIZE \
392 FIRST_32_SECOND_64(1ULL << 32, 1ULL << 36)
393# endif
394# else
395# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 48)
396# endif
397#elif defined(__sparc__)
398# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 52)
399#else
400# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 47)
401#endif
402
403// Whether the addresses are sign-extended from the VMA range to the word.
404// The SPARC64 Linux port implements this to split the VMA space into two
405// non-contiguous halves with a huge hole in the middle.
406#if defined(__sparc__) && SANITIZER_WORDSIZE == 64
407# define SANITIZER_SIGN_EXTENDED_ADDRESSES 1
408#else
409# define SANITIZER_SIGN_EXTENDED_ADDRESSES 0
410#endif
411
412// udi16 syscalls can only be used when the following conditions are
413// met:
414// * target is one of arm32, x86-32, sparc32, sh or m68k
415// * libc version is libc5, glibc-2.0, glibc-2.1 or glibc-2.2 to 2.15
416// built against > linux-2.2 kernel headers
417// Since we don't want to include libc headers here, we check the
418// target only.
419#if defined(__arm__) || SANITIZER_X32 || defined(__sparc__)
420# define SANITIZER_USES_UID16_SYSCALLS 1
421#else
422# define SANITIZER_USES_UID16_SYSCALLS 0
423#endif
424
425#if defined(__mips__)
426# define SANITIZER_POINTER_FORMAT_LENGTH FIRST_32_SECOND_64(8, 10)
427#else
428# define SANITIZER_POINTER_FORMAT_LENGTH FIRST_32_SECOND_64(8, 12)
429#endif
430
431/// \macro MSC_PREREQ
432/// \brief Is the compiler MSVC of at least the specified version?
433/// The common \param version values to check for are:
434/// * 1800: Microsoft Visual Studio 2013 / 12.0
435/// * 1900: Microsoft Visual Studio 2015 / 14.0
436#ifdef _MSC_VER
437# define MSC_PREREQ(version) (_MSC_VER >= (version))
438#else
439# define MSC_PREREQ(version) 0
440#endif
441
442#if SANITIZER_APPLE && defined(__x86_64__)
443# define SANITIZER_NON_UNIQUE_TYPEINFO 0
444#else
445# define SANITIZER_NON_UNIQUE_TYPEINFO 1
446#endif
447
448// On linux, some architectures had an ABI transition from 64-bit long double
449// (ie. same as double) to 128-bit long double. On those, glibc symbols
450// involving long doubles come in two versions, and we need to pass the
451// correct one to dlvsym when intercepting them.
452#if SANITIZER_LINUX && (SANITIZER_S390 || SANITIZER_PPC32 || SANITIZER_PPC64V1)
453# define SANITIZER_NLDBL_VERSION "GLIBC_2.4"
454#endif
455
456#if SANITIZER_GO == 0
457# define SANITIZER_GO 0
458#endif
459
460// On PowerPC and ARM Thumb, calling pthread_exit() causes LSan to detect leaks.
461// pthread_exit() performs unwinding that leads to dlopen'ing libgcc_s.so.
462// dlopen mallocs "libgcc_s.so" string which confuses LSan, it fails to realize
463// that this allocation happens in dynamic linker and should be ignored.
464#if SANITIZER_PPC || defined(__thumb__)
465# define SANITIZER_SUPPRESS_LEAK_ON_PTHREAD_EXIT 1
466#else
467# define SANITIZER_SUPPRESS_LEAK_ON_PTHREAD_EXIT 0
468#endif
469
470#if SANITIZER_FREEBSD || SANITIZER_APPLE || SANITIZER_NETBSD || \
471 SANITIZER_SOLARIS || SANITIZER_HAIKU
472# define SANITIZER_MADVISE_DONTNEED MADV_FREE
473#else
474# define SANITIZER_MADVISE_DONTNEED MADV_DONTNEED
475#endif
476
477// Older gcc have issues aligning to a constexpr, and require an integer.
478// See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56859 among others.
479#if defined(__powerpc__) || defined(__powerpc64__)
480# define SANITIZER_CACHE_LINE_SIZE 128
481#else
482# define SANITIZER_CACHE_LINE_SIZE 64
483#endif
484
485// Enable offline markup symbolizer for Fuchsia.
486#if SANITIZER_FUCHSIA
487# define SANITIZER_SYMBOLIZER_MARKUP 1
488#else
489# define SANITIZER_SYMBOLIZER_MARKUP 0
490#endif
491
492// Enable ability to support sanitizer initialization that is
493// compatible with the sanitizer library being loaded via
494// `dlopen()`.
495#if SANITIZER_APPLE
496# define SANITIZER_SUPPORTS_INIT_FOR_DLOPEN 1
497#else
498# define SANITIZER_SUPPORTS_INIT_FOR_DLOPEN 0
499#endif
500
501// SANITIZER_SUPPORTS_THREADLOCAL
502// 1 - THREADLOCAL macro is supported by target
503// 0 - THREADLOCAL macro is not supported by target
504#ifndef __has_feature
505// TODO: Support other compilers here
506# define SANITIZER_SUPPORTS_THREADLOCAL 1
507#else
508# if __has_feature(tls)
509# define SANITIZER_SUPPORTS_THREADLOCAL 1
510# else
511# define SANITIZER_SUPPORTS_THREADLOCAL 0
512# endif
513#endif
514
515#if defined(__thumb__) && defined(__linux__)
516// Workaround for
517// https://lab.llvm.org/buildbot/#/builders/clang-thumbv7-full-2stage
518// or
519// https://lab.llvm.org/staging/#/builders/clang-thumbv7-full-2stage
520// It fails *rss_limit_mb_test* without meaningful errors.
521# define SANITIZER_START_BACKGROUND_THREAD_IN_ASAN_INTERNAL 1
522#else
523# define SANITIZER_START_BACKGROUND_THREAD_IN_ASAN_INTERNAL 0
524#endif
525
526#if SANITIZER_LINUX
527# if SANITIZER_GLIBC
528// Workaround for
529// glibc/commit/3d3572f59059e2b19b8541ea648a6172136ec42e
530// Linux: Keep termios ioctl constants strictly internal
531# if __GLIBC_PREREQ(2, 41)
532# define SANITIZER_TERMIOS_IOCTL_CONSTANTS 0
533# else
534# define SANITIZER_TERMIOS_IOCTL_CONSTANTS 1
535# endif
536# else
537# define SANITIZER_TERMIOS_IOCTL_CONSTANTS 1
538# endif
539#endif
540
541#if SANITIZER_APPLE && SANITIZER_WORDSIZE == 64
542// MTE uses the lower half of the top byte.
543# define STRIP_MTE_TAG(addr) ((addr) & ~((uptr)0x0f << 56))
544#else
545# define STRIP_MTE_TAG(addr) (addr)
546#endif
547
548#endif // SANITIZER_PLATFORM_H
549