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) && \
17 !defined(__Fuchsia__) && !defined(__rtems__) && \
18 !(defined(__sun__) && defined(__svr4__))
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(__APPLE__)
60# define SANITIZER_MAC 1
61# include <TargetConditionals.h>
62# if TARGET_OS_OSX
63# define SANITIZER_OSX 1
64# else
65# define SANITIZER_OSX 0
66# endif
67# if TARGET_OS_IPHONE
68# define SANITIZER_IOS 1
69# else
70# define SANITIZER_IOS 0
71# endif
72# if TARGET_OS_SIMULATOR
73# define SANITIZER_IOSSIM 1
74# else
75# define SANITIZER_IOSSIM 0
76# endif
77#else
78# define SANITIZER_MAC 0
79# define SANITIZER_IOS 0
80# define SANITIZER_IOSSIM 0
81# define SANITIZER_OSX 0
82#endif
83
84#if defined(__APPLE__) && TARGET_OS_IPHONE && TARGET_OS_WATCH
85# define SANITIZER_WATCHOS 1
86#else
87# define SANITIZER_WATCHOS 0
88#endif
89
90#if defined(__APPLE__) && TARGET_OS_IPHONE && TARGET_OS_TV
91# define SANITIZER_TVOS 1
92#else
93# define SANITIZER_TVOS 0
94#endif
95
96#if defined(_WIN32)
97# define SANITIZER_WINDOWS 1
98#else
99# define SANITIZER_WINDOWS 0
100#endif
101
102#if defined(_WIN64)
103# define SANITIZER_WINDOWS64 1
104#else
105# define SANITIZER_WINDOWS64 0
106#endif
107
108#if defined(__ANDROID__)
109# define SANITIZER_ANDROID 1
110#else
111# define SANITIZER_ANDROID 0
112#endif
113
114#if defined(__Fuchsia__)
115# define SANITIZER_FUCHSIA 1
116#else
117# define SANITIZER_FUCHSIA 0
118#endif
119
120#if defined(__rtems__)
121# define SANITIZER_RTEMS 1
122#else
123# define SANITIZER_RTEMS 0
124#endif
125
126#define SANITIZER_POSIX \
127 (SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_MAC || \
128 SANITIZER_NETBSD || SANITIZER_SOLARIS)
129
130#if __LP64__ || defined(_WIN64)
131# define SANITIZER_WORDSIZE 64
132#else
133# define SANITIZER_WORDSIZE 32
134#endif
135
136#if SANITIZER_WORDSIZE == 64
137# define FIRST_32_SECOND_64(a, b) (b)
138#else
139# define FIRST_32_SECOND_64(a, b) (a)
140#endif
141
142#if defined(__x86_64__) && !defined(_LP64)
143# define SANITIZER_X32 1
144#else
145# define SANITIZER_X32 0
146#endif
147
148#if defined(__i386__) || defined(_M_IX86)
149# define SANITIZER_I386 1
150#else
151# define SANITIZER_I386 0
152#endif
153
154#if defined(__mips__)
155# define SANITIZER_MIPS 1
156# if defined(__mips64)
157# define SANITIZER_MIPS32 0
158# define SANITIZER_MIPS64 1
159# else
160# define SANITIZER_MIPS32 1
161# define SANITIZER_MIPS64 0
162# endif
163#else
164# define SANITIZER_MIPS 0
165# define SANITIZER_MIPS32 0
166# define SANITIZER_MIPS64 0
167#endif
168
169#if defined(__s390__)
170# define SANITIZER_S390 1
171# if defined(__s390x__)
172# define SANITIZER_S390_31 0
173# define SANITIZER_S390_64 1
174# else
175# define SANITIZER_S390_31 1
176# define SANITIZER_S390_64 0
177# endif
178#else
179# define SANITIZER_S390 0
180# define SANITIZER_S390_31 0
181# define SANITIZER_S390_64 0
182#endif
183
184#if defined(__powerpc__)
185# define SANITIZER_PPC 1
186# if defined(__powerpc64__)
187# define SANITIZER_PPC32 0
188# define SANITIZER_PPC64 1
189// 64-bit PPC has two ABIs (v1 and v2). The old powerpc64 target is
190// big-endian, and uses v1 ABI (known for its function descriptors),
191// while the new powerpc64le target is little-endian and uses v2.
192// In theory, you could convince gcc to compile for their evil twins
193// (eg. big-endian v2), but you won't find such combinations in the wild
194// (it'd require bootstrapping a whole system, which would be quite painful
195// - there's no target triple for that). LLVM doesn't support them either.
196# if _CALL_ELF == 2
197# define SANITIZER_PPC64V1 0
198# define SANITIZER_PPC64V2 1
199# else
200# define SANITIZER_PPC64V1 1
201# define SANITIZER_PPC64V2 0
202# endif
203# else
204# define SANITIZER_PPC32 1
205# define SANITIZER_PPC64 0
206# define SANITIZER_PPC64V1 0
207# define SANITIZER_PPC64V2 0
208# endif
209#else
210# define SANITIZER_PPC 0
211# define SANITIZER_PPC32 0
212# define SANITIZER_PPC64 0
213# define SANITIZER_PPC64V1 0
214# define SANITIZER_PPC64V2 0
215#endif
216
217#if defined(__arm__)
218# define SANITIZER_ARM 1
219#else
220# define SANITIZER_ARM 0
221#endif
222
223#if SANITIZER_SOLARIS && SANITIZER_WORDSIZE == 32
224# define SANITIZER_SOLARIS32 1
225#else
226# define SANITIZER_SOLARIS32 0
227#endif
228
229#if defined(__myriad2__)
230# define SANITIZER_MYRIAD2 1
231#else
232# define SANITIZER_MYRIAD2 0
233#endif
234
235#if defined(__riscv) && (__riscv_xlen == 64)
236#define SANITIZER_RISCV64 1
237#else
238#define SANITIZER_RISCV64 0
239#endif
240
241// By default we allow to use SizeClassAllocator64 on 64-bit platform.
242// But in some cases (e.g. AArch64's 39-bit address space) SizeClassAllocator64
243// does not work well and we need to fallback to SizeClassAllocator32.
244// For such platforms build this code with -DSANITIZER_CAN_USE_ALLOCATOR64=0 or
245// change the definition of SANITIZER_CAN_USE_ALLOCATOR64 here.
246#ifndef SANITIZER_CAN_USE_ALLOCATOR64
247# if (SANITIZER_ANDROID && defined(__aarch64__)) || SANITIZER_FUCHSIA
248# define SANITIZER_CAN_USE_ALLOCATOR64 1
249# elif defined(__mips64) || defined(__aarch64__)
250# define SANITIZER_CAN_USE_ALLOCATOR64 0
251# else
252# define SANITIZER_CAN_USE_ALLOCATOR64 (SANITIZER_WORDSIZE == 64)
253# endif
254#endif
255
256// The range of addresses which can be returned my mmap.
257// FIXME: this value should be different on different platforms. Larger values
258// will still work but will consume more memory for TwoLevelByteMap.
259#if defined(__mips__)
260#if SANITIZER_GO && defined(__mips64)
261#define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 47)
262#else
263# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 40)
264#endif
265#elif SANITIZER_RISCV64
266#define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 38)
267#elif defined(__aarch64__)
268# if SANITIZER_MAC
269# if SANITIZER_OSX || SANITIZER_IOSSIM
270# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 47)
271# else
272 // Darwin iOS/ARM64 has a 36-bit VMA, 64GiB VM
273# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 36)
274# endif
275# else
276# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 48)
277# endif
278#elif defined(__sparc__)
279#define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 52)
280#else
281# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 47)
282#endif
283
284// Whether the addresses are sign-extended from the VMA range to the word.
285// The SPARC64 Linux port implements this to split the VMA space into two
286// non-contiguous halves with a huge hole in the middle.
287#if defined(__sparc__) && SANITIZER_WORDSIZE == 64
288#define SANITIZER_SIGN_EXTENDED_ADDRESSES 1
289#else
290#define SANITIZER_SIGN_EXTENDED_ADDRESSES 0
291#endif
292
293// The AArch64 and RISC-V linux ports use the canonical syscall set as
294// mandated by the upstream linux community for all new ports. Other ports
295// may still use legacy syscalls.
296#ifndef SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
297# if (defined(__aarch64__) || defined(__riscv)) && SANITIZER_LINUX
298# define SANITIZER_USES_CANONICAL_LINUX_SYSCALLS 1
299# else
300# define SANITIZER_USES_CANONICAL_LINUX_SYSCALLS 0
301# endif
302#endif
303
304// udi16 syscalls can only be used when the following conditions are
305// met:
306// * target is one of arm32, x86-32, sparc32, sh or m68k
307// * libc version is libc5, glibc-2.0, glibc-2.1 or glibc-2.2 to 2.15
308// built against > linux-2.2 kernel headers
309// Since we don't want to include libc headers here, we check the
310// target only.
311#if defined(__arm__) || SANITIZER_X32 || defined(__sparc__)
312#define SANITIZER_USES_UID16_SYSCALLS 1
313#else
314#define SANITIZER_USES_UID16_SYSCALLS 0
315#endif
316
317#if defined(__mips__)
318# define SANITIZER_POINTER_FORMAT_LENGTH FIRST_32_SECOND_64(8, 10)
319#else
320# define SANITIZER_POINTER_FORMAT_LENGTH FIRST_32_SECOND_64(8, 12)
321#endif
322
323/// \macro MSC_PREREQ
324/// \brief Is the compiler MSVC of at least the specified version?
325/// The common \param version values to check for are:
326/// * 1800: Microsoft Visual Studio 2013 / 12.0
327/// * 1900: Microsoft Visual Studio 2015 / 14.0
328#ifdef _MSC_VER
329# define MSC_PREREQ(version) (_MSC_VER >= (version))
330#else
331# define MSC_PREREQ(version) 0
332#endif
333
334#if SANITIZER_MAC && !(defined(__arm64__) && SANITIZER_IOS)
335# define SANITIZER_NON_UNIQUE_TYPEINFO 0
336#else
337# define SANITIZER_NON_UNIQUE_TYPEINFO 1
338#endif
339
340// On linux, some architectures had an ABI transition from 64-bit long double
341// (ie. same as double) to 128-bit long double. On those, glibc symbols
342// involving long doubles come in two versions, and we need to pass the
343// correct one to dlvsym when intercepting them.
344#if SANITIZER_LINUX && (SANITIZER_S390 || SANITIZER_PPC32 || SANITIZER_PPC64V1)
345#define SANITIZER_NLDBL_VERSION "GLIBC_2.4"
346#endif
347
348#if SANITIZER_GO == 0
349# define SANITIZER_GO 0
350#endif
351
352// On PowerPC and ARM Thumb, calling pthread_exit() causes LSan to detect leaks.
353// pthread_exit() performs unwinding that leads to dlopen'ing libgcc_s.so.
354// dlopen mallocs "libgcc_s.so" string which confuses LSan, it fails to realize
355// that this allocation happens in dynamic linker and should be ignored.
356#if SANITIZER_PPC || defined(__thumb__)
357# define SANITIZER_SUPPRESS_LEAK_ON_PTHREAD_EXIT 1
358#else
359# define SANITIZER_SUPPRESS_LEAK_ON_PTHREAD_EXIT 0
360#endif
361
362#if SANITIZER_FREEBSD || SANITIZER_MAC || SANITIZER_NETBSD || \
363 SANITIZER_SOLARIS
364# define SANITIZER_MADVISE_DONTNEED MADV_FREE
365#else
366# define SANITIZER_MADVISE_DONTNEED MADV_DONTNEED
367#endif
368
369// Older gcc have issues aligning to a constexpr, and require an integer.
370// See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56859 among others.
371#if defined(__powerpc__) || defined(__powerpc64__)
372# define SANITIZER_CACHE_LINE_SIZE 128
373#else
374# define SANITIZER_CACHE_LINE_SIZE 64
375#endif
376
377// Enable offline markup symbolizer for Fuchsia and RTEMS.
378#if SANITIZER_FUCHSIA || SANITIZER_RTEMS
379#define SANITIZER_SYMBOLIZER_MARKUP 1
380#else
381#define SANITIZER_SYMBOLIZER_MARKUP 0
382#endif
383
384// Enable ability to support sanitizer initialization that is
385// compatible with the sanitizer library being loaded via
386// `dlopen()`.
387#if SANITIZER_MAC
388#define SANITIZER_SUPPORTS_INIT_FOR_DLOPEN 1
389#else
390#define SANITIZER_SUPPORTS_INIT_FOR_DLOPEN 0
391#endif
392
393#endif // SANITIZER_PLATFORM_H
394