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(__x86_64__) || defined(_M_X64)
142 #  define SANITIZER_X64 1
143 #else
144 #  define SANITIZER_X64 0
145 #endif
146 
147 #if defined(__i386__) || defined(_M_IX86)
148 #  define SANITIZER_I386 1
149 #else
150 #  define SANITIZER_I386 0
151 #endif
152 
153 #if defined(__mips__)
154 #  define SANITIZER_MIPS 1
155 #  if defined(__mips64)
156 #    define SANITIZER_MIPS32 0
157 #    define SANITIZER_MIPS64 1
158 #  else
159 #    define SANITIZER_MIPS32 1
160 #    define SANITIZER_MIPS64 0
161 #  endif
162 #else
163 #  define SANITIZER_MIPS 0
164 #  define SANITIZER_MIPS32 0
165 #  define SANITIZER_MIPS64 0
166 #endif
167 
168 #if defined(__s390__)
169 #  define SANITIZER_S390 1
170 #  if defined(__s390x__)
171 #    define SANITIZER_S390_31 0
172 #    define SANITIZER_S390_64 1
173 #  else
174 #    define SANITIZER_S390_31 1
175 #    define SANITIZER_S390_64 0
176 #  endif
177 #else
178 #  define SANITIZER_S390 0
179 #  define SANITIZER_S390_31 0
180 #  define SANITIZER_S390_64 0
181 #endif
182 
183 #if defined(__powerpc__)
184 #  define SANITIZER_PPC 1
185 #  if defined(__powerpc64__)
186 #    define SANITIZER_PPC32 0
187 #    define SANITIZER_PPC64 1
188 // 64-bit PPC has two ABIs (v1 and v2).  The old powerpc64 target is
189 // big-endian, and uses v1 ABI (known for its function descriptors),
190 // while the new powerpc64le target is little-endian and uses v2.
191 // In theory, you could convince gcc to compile for their evil twins
192 // (eg. big-endian v2), but you won't find such combinations in the wild
193 // (it'd require bootstrapping a whole system, which would be quite painful
194 // - there's no target triple for that).  LLVM doesn't support them either.
195 #    if _CALL_ELF == 2
196 #      define SANITIZER_PPC64V1 0
197 #      define SANITIZER_PPC64V2 1
198 #    else
199 #      define SANITIZER_PPC64V1 1
200 #      define SANITIZER_PPC64V2 0
201 #    endif
202 #  else
203 #    define SANITIZER_PPC32 1
204 #    define SANITIZER_PPC64 0
205 #    define SANITIZER_PPC64V1 0
206 #    define SANITIZER_PPC64V2 0
207 #  endif
208 #else
209 #  define SANITIZER_PPC 0
210 #  define SANITIZER_PPC32 0
211 #  define SANITIZER_PPC64 0
212 #  define SANITIZER_PPC64V1 0
213 #  define SANITIZER_PPC64V2 0
214 #endif
215 
216 #if defined(__arm__) || defined(_M_ARM)
217 #  define SANITIZER_ARM 1
218 #else
219 #  define SANITIZER_ARM 0
220 #endif
221 
222 #if defined(__aarch64__) || defined(_M_ARM64)
223 #  define SANITIZER_ARM64 1
224 #else
225 #  define SANITIZER_ARM64 0
226 #endif
227 
228 #if SANITIZER_SOLARIS && SANITIZER_WORDSIZE == 32
229 #  define SANITIZER_SOLARIS32 1
230 #else
231 #  define SANITIZER_SOLARIS32 0
232 #endif
233 
234 #if defined(__riscv) && (__riscv_xlen == 64)
235 #  define SANITIZER_RISCV64 1
236 #else
237 #  define SANITIZER_RISCV64 0
238 #endif
239 
240 // By default we allow to use SizeClassAllocator64 on 64-bit platform.
241 // But in some cases (e.g. AArch64's 39-bit address space) SizeClassAllocator64
242 // does not work well and we need to fallback to SizeClassAllocator32.
243 // For such platforms build this code with -DSANITIZER_CAN_USE_ALLOCATOR64=0 or
244 // change the definition of SANITIZER_CAN_USE_ALLOCATOR64 here.
245 #ifndef SANITIZER_CAN_USE_ALLOCATOR64
246 #  if (SANITIZER_ANDROID && defined(__aarch64__)) || SANITIZER_FUCHSIA
247 #    define SANITIZER_CAN_USE_ALLOCATOR64 1
248 #  elif defined(__mips64) || defined(__aarch64__)
249 #    define SANITIZER_CAN_USE_ALLOCATOR64 0
250 #  else
251 #    define SANITIZER_CAN_USE_ALLOCATOR64 (SANITIZER_WORDSIZE == 64)
252 #  endif
253 #endif
254 
255 // The range of addresses which can be returned my mmap.
256 // FIXME: this value should be different on different platforms.  Larger values
257 // will still work but will consume more memory for TwoLevelByteMap.
258 #if defined(__mips__)
259 #  if SANITIZER_GO && defined(__mips64)
260 #    define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 47)
261 #  else
262 #    define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 40)
263 #  endif
264 #elif SANITIZER_RISCV64
265 #  define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 38)
266 #elif defined(__aarch64__)
267 #  if SANITIZER_MAC
268 #    if SANITIZER_OSX || SANITIZER_IOSSIM
269 #      define SANITIZER_MMAP_RANGE_SIZE \
270         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 \
274         FIRST_32_SECOND_64(1ULL << 32, 1ULL << 36)
275 #    endif
276 #  else
277 #    define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 48)
278 #  endif
279 #elif defined(__sparc__)
280 #  define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 52)
281 #else
282 #  define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 47)
283 #endif
284 
285 // Whether the addresses are sign-extended from the VMA range to the word.
286 // The SPARC64 Linux port implements this to split the VMA space into two
287 // non-contiguous halves with a huge hole in the middle.
288 #if defined(__sparc__) && SANITIZER_WORDSIZE == 64
289 #  define SANITIZER_SIGN_EXTENDED_ADDRESSES 1
290 #else
291 #  define SANITIZER_SIGN_EXTENDED_ADDRESSES 0
292 #endif
293 
294 // The AArch64 and RISC-V linux ports use the canonical syscall set as
295 // mandated by the upstream linux community for all new ports. Other ports
296 // may still use legacy syscalls.
297 #ifndef SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
298 #  if (defined(__aarch64__) || defined(__riscv) || defined(__hexagon__)) && \
299       SANITIZER_LINUX
300 #    define SANITIZER_USES_CANONICAL_LINUX_SYSCALLS 1
301 #  else
302 #    define SANITIZER_USES_CANONICAL_LINUX_SYSCALLS 0
303 #  endif
304 #endif
305 
306 // udi16 syscalls can only be used when the following conditions are
307 // met:
308 // * target is one of arm32, x86-32, sparc32, sh or m68k
309 // * libc version is libc5, glibc-2.0, glibc-2.1 or glibc-2.2 to 2.15
310 //   built against > linux-2.2 kernel headers
311 // Since we don't want to include libc headers here, we check the
312 // target only.
313 #if defined(__arm__) || SANITIZER_X32 || defined(__sparc__)
314 #  define SANITIZER_USES_UID16_SYSCALLS 1
315 #else
316 #  define SANITIZER_USES_UID16_SYSCALLS 0
317 #endif
318 
319 #if defined(__mips__)
320 #  define SANITIZER_POINTER_FORMAT_LENGTH FIRST_32_SECOND_64(8, 10)
321 #else
322 #  define SANITIZER_POINTER_FORMAT_LENGTH FIRST_32_SECOND_64(8, 12)
323 #endif
324 
325 /// \macro MSC_PREREQ
326 /// \brief Is the compiler MSVC of at least the specified version?
327 /// The common \param version values to check for are:
328 ///  * 1800: Microsoft Visual Studio 2013 / 12.0
329 ///  * 1900: Microsoft Visual Studio 2015 / 14.0
330 #ifdef _MSC_VER
331 #  define MSC_PREREQ(version) (_MSC_VER >= (version))
332 #else
333 #  define MSC_PREREQ(version) 0
334 #endif
335 
336 #if SANITIZER_MAC && !(defined(__arm64__) && SANITIZER_IOS)
337 #  define SANITIZER_NON_UNIQUE_TYPEINFO 0
338 #else
339 #  define SANITIZER_NON_UNIQUE_TYPEINFO 1
340 #endif
341 
342 // On linux, some architectures had an ABI transition from 64-bit long double
343 // (ie. same as double) to 128-bit long double.  On those, glibc symbols
344 // involving long doubles come in two versions, and we need to pass the
345 // correct one to dlvsym when intercepting them.
346 #if SANITIZER_LINUX && (SANITIZER_S390 || SANITIZER_PPC32 || SANITIZER_PPC64V1)
347 #  define SANITIZER_NLDBL_VERSION "GLIBC_2.4"
348 #endif
349 
350 #if SANITIZER_GO == 0
351 #  define SANITIZER_GO 0
352 #endif
353 
354 // On PowerPC and ARM Thumb, calling pthread_exit() causes LSan to detect leaks.
355 // pthread_exit() performs unwinding that leads to dlopen'ing libgcc_s.so.
356 // dlopen mallocs "libgcc_s.so" string which confuses LSan, it fails to realize
357 // that this allocation happens in dynamic linker and should be ignored.
358 #if SANITIZER_PPC || defined(__thumb__)
359 #  define SANITIZER_SUPPRESS_LEAK_ON_PTHREAD_EXIT 1
360 #else
361 #  define SANITIZER_SUPPRESS_LEAK_ON_PTHREAD_EXIT 0
362 #endif
363 
364 #if SANITIZER_FREEBSD || SANITIZER_MAC || SANITIZER_NETBSD || SANITIZER_SOLARIS
365 #  define SANITIZER_MADVISE_DONTNEED MADV_FREE
366 #else
367 #  define SANITIZER_MADVISE_DONTNEED MADV_DONTNEED
368 #endif
369 
370 // Older gcc have issues aligning to a constexpr, and require an integer.
371 // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56859 among others.
372 #if defined(__powerpc__) || defined(__powerpc64__)
373 #  define SANITIZER_CACHE_LINE_SIZE 128
374 #else
375 #  define SANITIZER_CACHE_LINE_SIZE 64
376 #endif
377 
378 // Enable offline markup symbolizer for Fuchsia.
379 #if SANITIZER_FUCHSIA
380 #  define SANITIZER_SYMBOLIZER_MARKUP 1
381 #else
382 #  define SANITIZER_SYMBOLIZER_MARKUP 0
383 #endif
384 
385 // Enable ability to support sanitizer initialization that is
386 // compatible with the sanitizer library being loaded via
387 // `dlopen()`.
388 #if SANITIZER_MAC
389 #  define SANITIZER_SUPPORTS_INIT_FOR_DLOPEN 1
390 #else
391 #  define SANITIZER_SUPPORTS_INIT_FOR_DLOPEN 0
392 #endif
393 
394 // SANITIZER_SUPPORTS_THREADLOCAL
395 // 1 - THREADLOCAL macro is supported by target
396 // 0 - THREADLOCAL macro is not supported by target
397 #ifndef __has_feature
398 // TODO: Support other compilers here
399 #  define SANITIZER_SUPPORTS_THREADLOCAL 1
400 #else
401 #  if __has_feature(tls)
402 #    define SANITIZER_SUPPORTS_THREADLOCAL 1
403 #  else
404 #    define SANITIZER_SUPPORTS_THREADLOCAL 0
405 #  endif
406 #endif
407 
408 #if defined(__thumb__) && defined(__linux__)
409 // Workaround for
410 // https://lab.llvm.org/buildbot/#/builders/clang-thumbv7-full-2stage
411 // or
412 // https://lab.llvm.org/staging/#/builders/clang-thumbv7-full-2stage
413 // It fails *rss_limit_mb_test* without meaningful errors.
414 #  define SANITIZER_START_BACKGROUND_THREAD_IN_ASAN_INTERNAL 1
415 #else
416 #  define SANITIZER_START_BACKGROUND_THREAD_IN_ASAN_INTERNAL 0
417 #endif
418 
419 #endif  // SANITIZER_PLATFORM_H
420