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