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