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