1251034Sed//===-- sanitizer_platform.h ------------------------------------*- C++ -*-===//
2251034Sed//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6251034Sed//
7251034Sed//===----------------------------------------------------------------------===//
8251034Sed//
9251034Sed// Common platform macros.
10251034Sed//===----------------------------------------------------------------------===//
11251034Sed
12251034Sed#ifndef SANITIZER_PLATFORM_H
13251034Sed#define SANITIZER_PLATFORM_H
14251034Sed
15321369Sdim#if !defined(__linux__) && !defined(__FreeBSD__) && !defined(__NetBSD__) && \
16341825Sdim  !defined(__OpenBSD__) && !defined(__APPLE__) && !defined(_WIN32) && \
17341825Sdim  !defined(__Fuchsia__) && !defined(__rtems__) && \
18327952Sdim  !(defined(__sun__) && defined(__svr4__))
19251034Sed# error "This operating system is not supported"
20251034Sed#endif
21251034Sed
22251034Sed#if defined(__linux__)
23251034Sed# define SANITIZER_LINUX   1
24251034Sed#else
25251034Sed# define SANITIZER_LINUX   0
26251034Sed#endif
27251034Sed
28276789Sdim#if defined(__FreeBSD__)
29276789Sdim# define SANITIZER_FREEBSD 1
30276789Sdim#else
31276789Sdim# define SANITIZER_FREEBSD 0
32276789Sdim#endif
33276789Sdim
34321369Sdim#if defined(__NetBSD__)
35321369Sdim# define SANITIZER_NETBSD 1
36321369Sdim#else
37321369Sdim# define SANITIZER_NETBSD 0
38321369Sdim#endif
39321369Sdim
40341825Sdim#if defined(__OpenBSD__)
41341825Sdim# define SANITIZER_OPENBSD 1
42341825Sdim#else
43341825Sdim# define SANITIZER_OPENBSD 0
44341825Sdim#endif
45341825Sdim
46327952Sdim#if defined(__sun__) && defined(__svr4__)
47327952Sdim# define SANITIZER_SOLARIS 1
48327952Sdim#else
49327952Sdim# define SANITIZER_SOLARIS 0
50327952Sdim#endif
51327952Sdim
52251034Sed#if defined(__APPLE__)
53251034Sed# define SANITIZER_MAC     1
54274201Sdim# include <TargetConditionals.h>
55274201Sdim# if TARGET_OS_IPHONE
56274201Sdim#  define SANITIZER_IOS    1
57274201Sdim# else
58274201Sdim#  define SANITIZER_IOS    0
59274201Sdim# endif
60327952Sdim# if TARGET_OS_SIMULATOR
61288943Sdim#  define SANITIZER_IOSSIM 1
62288943Sdim# else
63288943Sdim#  define SANITIZER_IOSSIM 0
64288943Sdim# endif
65251034Sed#else
66251034Sed# define SANITIZER_MAC     0
67274201Sdim# define SANITIZER_IOS     0
68288943Sdim# define SANITIZER_IOSSIM  0
69251034Sed#endif
70251034Sed
71309124Sdim#if defined(__APPLE__) && TARGET_OS_IPHONE && TARGET_OS_WATCH
72309124Sdim# define SANITIZER_WATCHOS 1
73309124Sdim#else
74309124Sdim# define SANITIZER_WATCHOS 0
75309124Sdim#endif
76309124Sdim
77309124Sdim#if defined(__APPLE__) && TARGET_OS_IPHONE && TARGET_OS_TV
78309124Sdim# define SANITIZER_TVOS 1
79309124Sdim#else
80309124Sdim# define SANITIZER_TVOS 0
81309124Sdim#endif
82309124Sdim
83251034Sed#if defined(_WIN32)
84251034Sed# define SANITIZER_WINDOWS 1
85251034Sed#else
86251034Sed# define SANITIZER_WINDOWS 0
87251034Sed#endif
88251034Sed
89309124Sdim#if defined(_WIN64)
90309124Sdim# define SANITIZER_WINDOWS64 1
91309124Sdim#else
92309124Sdim# define SANITIZER_WINDOWS64 0
93309124Sdim#endif
94309124Sdim
95276789Sdim#if defined(__ANDROID__)
96251034Sed# define SANITIZER_ANDROID 1
97251034Sed#else
98251034Sed# define SANITIZER_ANDROID 0
99251034Sed#endif
100251034Sed
101327952Sdim#if defined(__Fuchsia__)
102327952Sdim# define SANITIZER_FUCHSIA 1
103327952Sdim#else
104327952Sdim# define SANITIZER_FUCHSIA 0
105327952Sdim#endif
106327952Sdim
107341825Sdim#if defined(__rtems__)
108341825Sdim# define SANITIZER_RTEMS 1
109341825Sdim#else
110341825Sdim# define SANITIZER_RTEMS 0
111341825Sdim#endif
112341825Sdim
113321369Sdim#define SANITIZER_POSIX \
114327952Sdim  (SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_MAC || \
115341825Sdim    SANITIZER_NETBSD || SANITIZER_OPENBSD || SANITIZER_SOLARIS)
116251034Sed
117276789Sdim#if __LP64__ || defined(_WIN64)
118276789Sdim#  define SANITIZER_WORDSIZE 64
119276789Sdim#else
120276789Sdim#  define SANITIZER_WORDSIZE 32
121276789Sdim#endif
122276789Sdim
123276789Sdim#if SANITIZER_WORDSIZE == 64
124276789Sdim# define FIRST_32_SECOND_64(a, b) (b)
125276789Sdim#else
126276789Sdim# define FIRST_32_SECOND_64(a, b) (a)
127276789Sdim#endif
128276789Sdim
129276789Sdim#if defined(__x86_64__) && !defined(_LP64)
130276789Sdim# define SANITIZER_X32 1
131276789Sdim#else
132276789Sdim# define SANITIZER_X32 0
133276789Sdim#endif
134276789Sdim
135309124Sdim#if defined(__mips__)
136309124Sdim# define SANITIZER_MIPS 1
137309124Sdim# if defined(__mips64)
138309124Sdim#  define SANITIZER_MIPS32 0
139309124Sdim#  define SANITIZER_MIPS64 1
140309124Sdim# else
141309124Sdim#  define SANITIZER_MIPS32 1
142309124Sdim#  define SANITIZER_MIPS64 0
143309124Sdim# endif
144309124Sdim#else
145309124Sdim# define SANITIZER_MIPS 0
146309124Sdim# define SANITIZER_MIPS32 0
147309124Sdim# define SANITIZER_MIPS64 0
148309124Sdim#endif
149309124Sdim
150309124Sdim#if defined(__s390__)
151309124Sdim# define SANITIZER_S390 1
152309124Sdim# if defined(__s390x__)
153309124Sdim#  define SANITIZER_S390_31 0
154309124Sdim#  define SANITIZER_S390_64 1
155309124Sdim# else
156309124Sdim#  define SANITIZER_S390_31 1
157309124Sdim#  define SANITIZER_S390_64 0
158309124Sdim# endif
159309124Sdim#else
160309124Sdim# define SANITIZER_S390 0
161309124Sdim# define SANITIZER_S390_31 0
162309124Sdim# define SANITIZER_S390_64 0
163309124Sdim#endif
164309124Sdim
165309124Sdim#if defined(__powerpc__)
166309124Sdim# define SANITIZER_PPC 1
167309124Sdim# if defined(__powerpc64__)
168309124Sdim#  define SANITIZER_PPC32 0
169309124Sdim#  define SANITIZER_PPC64 1
170309124Sdim// 64-bit PPC has two ABIs (v1 and v2).  The old powerpc64 target is
171309124Sdim// big-endian, and uses v1 ABI (known for its function descriptors),
172309124Sdim// while the new powerpc64le target is little-endian and uses v2.
173309124Sdim// In theory, you could convince gcc to compile for their evil twins
174309124Sdim// (eg. big-endian v2), but you won't find such combinations in the wild
175309124Sdim// (it'd require bootstrapping a whole system, which would be quite painful
176309124Sdim// - there's no target triple for that).  LLVM doesn't support them either.
177309124Sdim#  if _CALL_ELF == 2
178309124Sdim#   define SANITIZER_PPC64V1 0
179309124Sdim#   define SANITIZER_PPC64V2 1
180309124Sdim#  else
181309124Sdim#   define SANITIZER_PPC64V1 1
182309124Sdim#   define SANITIZER_PPC64V2 0
183309124Sdim#  endif
184309124Sdim# else
185309124Sdim#  define SANITIZER_PPC32 1
186309124Sdim#  define SANITIZER_PPC64 0
187309124Sdim#  define SANITIZER_PPC64V1 0
188309124Sdim#  define SANITIZER_PPC64V2 0
189309124Sdim# endif
190309124Sdim#else
191309124Sdim# define SANITIZER_PPC 0
192309124Sdim# define SANITIZER_PPC32 0
193309124Sdim# define SANITIZER_PPC64 0
194309124Sdim# define SANITIZER_PPC64V1 0
195309124Sdim# define SANITIZER_PPC64V2 0
196309124Sdim#endif
197309124Sdim
198321369Sdim#if defined(__arm__)
199321369Sdim# define SANITIZER_ARM 1
200321369Sdim#else
201321369Sdim# define SANITIZER_ARM 0
202321369Sdim#endif
203321369Sdim
204327952Sdim#if SANITIZER_SOLARIS && SANITIZER_WORDSIZE == 32
205327952Sdim# define SANITIZER_SOLARIS32 1
206327952Sdim#else
207327952Sdim# define SANITIZER_SOLARIS32 0
208327952Sdim#endif
209327952Sdim
210341825Sdim#if defined(__myriad2__)
211341825Sdim# define SANITIZER_MYRIAD2 1
212341825Sdim#else
213341825Sdim# define SANITIZER_MYRIAD2 0
214341825Sdim#endif
215341825Sdim
216276789Sdim// By default we allow to use SizeClassAllocator64 on 64-bit platform.
217276789Sdim// But in some cases (e.g. AArch64's 39-bit address space) SizeClassAllocator64
218276789Sdim// does not work well and we need to fallback to SizeClassAllocator32.
219276789Sdim// For such platforms build this code with -DSANITIZER_CAN_USE_ALLOCATOR64=0 or
220276789Sdim// change the definition of SANITIZER_CAN_USE_ALLOCATOR64 here.
221276789Sdim#ifndef SANITIZER_CAN_USE_ALLOCATOR64
222327952Sdim# if (SANITIZER_ANDROID && defined(__aarch64__)) || SANITIZER_FUCHSIA
223314564Sdim#  define SANITIZER_CAN_USE_ALLOCATOR64 1
224314564Sdim# elif defined(__mips64) || defined(__aarch64__)
225276789Sdim#  define SANITIZER_CAN_USE_ALLOCATOR64 0
226276789Sdim# else
227276789Sdim#  define SANITIZER_CAN_USE_ALLOCATOR64 (SANITIZER_WORDSIZE == 64)
228276789Sdim# endif
229276789Sdim#endif
230276789Sdim
231276789Sdim// The range of addresses which can be returned my mmap.
232296417Sdim// FIXME: this value should be different on different platforms.  Larger values
233296417Sdim// will still work but will consume more memory for TwoLevelByteMap.
234296417Sdim#if defined(__mips__)
235276789Sdim# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 40)
236309124Sdim#elif defined(__aarch64__)
237344779Sdim# if SANITIZER_MAC
238344779Sdim// Darwin iOS/ARM64 has a 36-bit VMA, 64GiB VM
239344779Sdim#  define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 36)
240344779Sdim# else
241344779Sdim#  define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 48)
242344779Sdim# endif
243353358Sdim#elif defined(__sparc__)
244353358Sdim#define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 52)
245276789Sdim#else
246276789Sdim# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 47)
247276789Sdim#endif
248276789Sdim
249353358Sdim// Whether the addresses are sign-extended from the VMA range to the word.
250353358Sdim// The SPARC64 Linux port implements this to split the VMA space into two
251353358Sdim// non-contiguous halves with a huge hole in the middle.
252353358Sdim#if defined(__sparc__) && SANITIZER_WORDSIZE == 64
253353358Sdim#define SANITIZER_SIGN_EXTENDED_ADDRESSES 1
254353358Sdim#else
255353358Sdim#define SANITIZER_SIGN_EXTENDED_ADDRESSES 0
256353358Sdim#endif
257353358Sdim
258360784Sdim// The AArch64 and RISC-V linux ports use the canonical syscall set as
259360784Sdim// mandated by the upstream linux community for all new ports. Other ports
260360784Sdim// may still use legacy syscalls.
261276789Sdim#ifndef SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
262360784Sdim# if (defined(__aarch64__) || defined(__riscv)) && SANITIZER_LINUX
263276789Sdim# define SANITIZER_USES_CANONICAL_LINUX_SYSCALLS 1
264276789Sdim# else
265276789Sdim# define SANITIZER_USES_CANONICAL_LINUX_SYSCALLS 0
266276789Sdim# endif
267276789Sdim#endif
268276789Sdim
269288943Sdim// udi16 syscalls can only be used when the following conditions are
270288943Sdim// met:
271288943Sdim// * target is one of arm32, x86-32, sparc32, sh or m68k
272288943Sdim// * libc version is libc5, glibc-2.0, glibc-2.1 or glibc-2.2 to 2.15
273288943Sdim//   built against > linux-2.2 kernel headers
274288943Sdim// Since we don't want to include libc headers here, we check the
275288943Sdim// target only.
276288943Sdim#if defined(__arm__) || SANITIZER_X32 || defined(__sparc__)
277288943Sdim#define SANITIZER_USES_UID16_SYSCALLS 1
278288943Sdim#else
279288943Sdim#define SANITIZER_USES_UID16_SYSCALLS 0
280288943Sdim#endif
281288943Sdim
282296417Sdim#if defined(__mips__)
283276789Sdim# define SANITIZER_POINTER_FORMAT_LENGTH FIRST_32_SECOND_64(8, 10)
284276789Sdim#else
285276789Sdim# define SANITIZER_POINTER_FORMAT_LENGTH FIRST_32_SECOND_64(8, 12)
286276789Sdim#endif
287276789Sdim
288296417Sdim/// \macro MSC_PREREQ
289296417Sdim/// \brief Is the compiler MSVC of at least the specified version?
290296417Sdim/// The common \param version values to check for are:
291296417Sdim///  * 1800: Microsoft Visual Studio 2013 / 12.0
292296417Sdim///  * 1900: Microsoft Visual Studio 2015 / 14.0
293296417Sdim#ifdef _MSC_VER
294296417Sdim# define MSC_PREREQ(version) (_MSC_VER >= (version))
295296417Sdim#else
296296417Sdim# define MSC_PREREQ(version) 0
297296417Sdim#endif
298296417Sdim
299353358Sdim#if SANITIZER_MAC && !(defined(__arm64__) && SANITIZER_IOS)
300353358Sdim# define SANITIZER_NON_UNIQUE_TYPEINFO 0
301353358Sdim#else
302309124Sdim# define SANITIZER_NON_UNIQUE_TYPEINFO 1
303309124Sdim#endif
304309124Sdim
305309124Sdim// On linux, some architectures had an ABI transition from 64-bit long double
306309124Sdim// (ie. same as double) to 128-bit long double.  On those, glibc symbols
307309124Sdim// involving long doubles come in two versions, and we need to pass the
308309124Sdim// correct one to dlvsym when intercepting them.
309309124Sdim#if SANITIZER_LINUX && (SANITIZER_S390 || SANITIZER_PPC32 || SANITIZER_PPC64V1)
310309124Sdim#define SANITIZER_NLDBL_VERSION "GLIBC_2.4"
311309124Sdim#endif
312309124Sdim
313314564Sdim#if SANITIZER_GO == 0
314314564Sdim# define SANITIZER_GO 0
315314564Sdim#endif
316314564Sdim
317321369Sdim// On PowerPC and ARM Thumb, calling pthread_exit() causes LSan to detect leaks.
318321369Sdim// pthread_exit() performs unwinding that leads to dlopen'ing libgcc_s.so.
319321369Sdim// dlopen mallocs "libgcc_s.so" string which confuses LSan, it fails to realize
320321369Sdim// that this allocation happens in dynamic linker and should be ignored.
321321369Sdim#if SANITIZER_PPC || defined(__thumb__)
322321369Sdim# define SANITIZER_SUPPRESS_LEAK_ON_PTHREAD_EXIT 1
323321369Sdim#else
324321369Sdim# define SANITIZER_SUPPRESS_LEAK_ON_PTHREAD_EXIT 0
325321369Sdim#endif
326321369Sdim
327341825Sdim#if SANITIZER_FREEBSD || SANITIZER_MAC || SANITIZER_NETBSD || \
328341825Sdim  SANITIZER_OPENBSD || SANITIZER_SOLARIS
329327952Sdim# define SANITIZER_MADVISE_DONTNEED MADV_FREE
330327952Sdim#else
331327952Sdim# define SANITIZER_MADVISE_DONTNEED MADV_DONTNEED
332327952Sdim#endif
333321369Sdim
334341825Sdim// Older gcc have issues aligning to a constexpr, and require an integer.
335341825Sdim// See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56859 among others.
336341825Sdim#if defined(__powerpc__) || defined(__powerpc64__)
337341825Sdim# define SANITIZER_CACHE_LINE_SIZE 128
338341825Sdim#else
339341825Sdim# define SANITIZER_CACHE_LINE_SIZE 64
340341825Sdim#endif
341341825Sdim
342341825Sdim// Enable offline markup symbolizer for Fuchsia and RTEMS.
343341825Sdim#if SANITIZER_FUCHSIA || SANITIZER_RTEMS
344341825Sdim#define SANITIZER_SYMBOLIZER_MARKUP 1
345341825Sdim#else
346341825Sdim#define SANITIZER_SYMBOLIZER_MARKUP 0
347341825Sdim#endif
348341825Sdim
349344779Sdim// Enable ability to support sanitizer initialization that is
350344779Sdim// compatible with the sanitizer library being loaded via
351344779Sdim// `dlopen()`.
352344779Sdim#if SANITIZER_MAC
353344779Sdim#define SANITIZER_SUPPORTS_INIT_FOR_DLOPEN 1
354344779Sdim#else
355344779Sdim#define SANITIZER_SUPPORTS_INIT_FOR_DLOPEN 0
356344779Sdim#endif
357344779Sdim
358251034Sed#endif // SANITIZER_PLATFORM_H
359