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