508 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8//9// Common platform macros.10//===----------------------------------------------------------------------===//11 12#ifndef SANITIZER_PLATFORM_H13#define SANITIZER_PLATFORM_H14 15#if !defined(__linux__) && !defined(__FreeBSD__) && !defined(__NetBSD__) && \16 !defined(__APPLE__) && !defined(_WIN32) && !defined(__Fuchsia__) && \17 !(defined(__sun__) && defined(__svr4__)) && !defined(__HAIKU__) && \18 !defined(__wasi__)19# error "This operating system is not supported"20#endif21 22// Get __GLIBC__ on a glibc platform. Exclude Android: features.h includes C23// function declarations into a .S file which doesn't compile.24// https://crbug.com/116274125#if __has_include(<features.h>) && !defined(__ANDROID__)26# include <features.h>27#endif28 29#if defined(__linux__)30# define SANITIZER_LINUX 131#else32# define SANITIZER_LINUX 033#endif34 35#if defined(__GLIBC__)36# define SANITIZER_GLIBC 137#else38# define SANITIZER_GLIBC 039#endif40 41#if defined(__FreeBSD__)42# define SANITIZER_FREEBSD 143#else44# define SANITIZER_FREEBSD 045#endif46 47#if defined(__NetBSD__)48# define SANITIZER_NETBSD 149#else50# define SANITIZER_NETBSD 051#endif52 53#if defined(__sun__) && defined(__svr4__)54# define SANITIZER_SOLARIS 155#else56# define SANITIZER_SOLARIS 057#endif58 59#if defined(__HAIKU__)60# define SANITIZER_HAIKU 161#else62# define SANITIZER_HAIKU 063#endif64 65#if defined(__wasi__)66# define SANITIZER_WASI 167#else68# define SANITIZER_WASI 069#endif70 71// - SANITIZER_APPLE: all Apple code72// - TARGET_OS_OSX: macOS73// - SANITIZER_IOS: devices (iOS and iOS-like)74// - SANITIZER_WATCHOS75// - SANITIZER_TVOS76// - SANITIZER_IOSSIM: simulators (iOS and iOS-like)77// - SANITIZER_DRIVERKIT78#if defined(__APPLE__)79# define SANITIZER_APPLE 180# include <TargetConditionals.h>81# if TARGET_OS_OSX82# define SANITIZER_OSX 183# else84# define SANITIZER_OSX 085# endif86# if TARGET_OS_IPHONE87# define SANITIZER_IOS 188# else89# define SANITIZER_IOS 090# endif91# if TARGET_OS_WATCH92# define SANITIZER_WATCHOS 193# else94# define SANITIZER_WATCHOS 095# endif96# if TARGET_OS_TV97# define SANITIZER_TVOS 198# else99# define SANITIZER_TVOS 0100# endif101# if TARGET_OS_SIMULATOR102# define SANITIZER_IOSSIM 1103# else104# define SANITIZER_IOSSIM 0105# endif106# if defined(TARGET_OS_DRIVERKIT) && TARGET_OS_DRIVERKIT107# define SANITIZER_DRIVERKIT 1108# else109# define SANITIZER_DRIVERKIT 0110# endif111#else112# define SANITIZER_APPLE 0113# define SANITIZER_OSX 0114# define SANITIZER_IOS 0115# define SANITIZER_WATCHOS 0116# define SANITIZER_TVOS 0117# define SANITIZER_IOSSIM 0118# define SANITIZER_DRIVERKIT 0119#endif120 121#if defined(_WIN32)122# define SANITIZER_WINDOWS 1123#else124# define SANITIZER_WINDOWS 0125#endif126 127#if defined(_WIN64)128# define SANITIZER_WINDOWS64 1129#else130# define SANITIZER_WINDOWS64 0131#endif132 133#if defined(__ANDROID__)134# define SANITIZER_ANDROID 1135#else136# define SANITIZER_ANDROID 0137#endif138 139#if defined(__Fuchsia__)140# define SANITIZER_FUCHSIA 1141#else142# define SANITIZER_FUCHSIA 0143#endif144 145// Assume linux that is not glibc or android is musl libc.146#if SANITIZER_LINUX && !SANITIZER_GLIBC && !SANITIZER_ANDROID147# define SANITIZER_MUSL 1148#else149# define SANITIZER_MUSL 0150#endif151 152#define SANITIZER_POSIX \153 (SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_APPLE || \154 SANITIZER_NETBSD || SANITIZER_SOLARIS || SANITIZER_HAIKU)155 156#if __LP64__ || defined(_WIN64)157# define SANITIZER_WORDSIZE 64158#else159# define SANITIZER_WORDSIZE 32160#endif161 162#if SANITIZER_WORDSIZE == 64163# define FIRST_32_SECOND_64(a, b) (b)164#else165# define FIRST_32_SECOND_64(a, b) (a)166#endif167 168#if defined(__x86_64__) && !defined(_LP64)169# define SANITIZER_X32 1170#else171# define SANITIZER_X32 0172#endif173 174#if defined(__x86_64__) || defined(_M_X64)175# define SANITIZER_X64 1176#else177# define SANITIZER_X64 0178#endif179 180#if defined(__i386__) || defined(_M_IX86)181# define SANITIZER_I386 1182#else183# define SANITIZER_I386 0184#endif185 186#if defined(__mips__)187# define SANITIZER_MIPS 1188# if defined(__mips64) && _MIPS_SIM == _ABI64189# define SANITIZER_MIPS32 0190# define SANITIZER_MIPS64 1191# else192# define SANITIZER_MIPS32 1193# define SANITIZER_MIPS64 0194# endif195#else196# define SANITIZER_MIPS 0197# define SANITIZER_MIPS32 0198# define SANITIZER_MIPS64 0199#endif200 201#if defined(__s390__)202# define SANITIZER_S390 1203# if defined(__s390x__)204# define SANITIZER_S390_31 0205# define SANITIZER_S390_64 1206# else207# define SANITIZER_S390_31 1208# define SANITIZER_S390_64 0209# endif210#else211# define SANITIZER_S390 0212# define SANITIZER_S390_31 0213# define SANITIZER_S390_64 0214#endif215 216#if defined(__sparc__)217# define SANITIZER_SPARC 1218# if defined(__arch64__)219# define SANITIZER_SPARC32 0220# define SANITIZER_SPARC64 1221# else222# define SANITIZER_SPARC32 1223# define SANITIZER_SPARC64 0224# endif225#else226# define SANITIZER_SPARC 0227# define SANITIZER_SPARC32 0228# define SANITIZER_SPARC64 0229#endif230 231#if defined(__powerpc__)232# define SANITIZER_PPC 1233# if defined(__powerpc64__)234# define SANITIZER_PPC32 0235# define SANITIZER_PPC64 1236// 64-bit PPC has two ABIs (v1 and v2). The old powerpc64 target is237// big-endian, and uses v1 ABI (known for its function descriptors),238// while the new powerpc64le target is little-endian and uses v2.239// In theory, you could convince gcc to compile for their evil twins240// (eg. big-endian v2), but you won't find such combinations in the wild241// (it'd require bootstrapping a whole system, which would be quite painful242// - there's no target triple for that). LLVM doesn't support them either.243# if _CALL_ELF == 2244# define SANITIZER_PPC64V1 0245# define SANITIZER_PPC64V2 1246# else247# define SANITIZER_PPC64V1 1248# define SANITIZER_PPC64V2 0249# endif250# else251# define SANITIZER_PPC32 1252# define SANITIZER_PPC64 0253# define SANITIZER_PPC64V1 0254# define SANITIZER_PPC64V2 0255# endif256#else257# define SANITIZER_PPC 0258# define SANITIZER_PPC32 0259# define SANITIZER_PPC64 0260# define SANITIZER_PPC64V1 0261# define SANITIZER_PPC64V2 0262#endif263 264#if defined(__arm__) || defined(_M_ARM)265# define SANITIZER_ARM 1266#else267# define SANITIZER_ARM 0268#endif269 270#if defined(__aarch64__) || defined(_M_ARM64)271# define SANITIZER_ARM64 1272#else273# define SANITIZER_ARM64 0274#endif275 276#if SANITIZER_WINDOWS64 && SANITIZER_ARM64277# define SANITIZER_WINDOWS_ARM64 1278# define SANITIZER_WINDOWS_x64 0279#elif SANITIZER_WINDOWS64 && !SANITIZER_ARM64280# define SANITIZER_WINDOWS_ARM64 0281# define SANITIZER_WINDOWS_x64 1282#else283# define SANITIZER_WINDOWS_ARM64 0284# define SANITIZER_WINDOWS_x64 0285#endif286 287#if SANITIZER_SOLARIS && SANITIZER_WORDSIZE == 32288# define SANITIZER_SOLARIS32 1289#else290# define SANITIZER_SOLARIS32 0291#endif292 293#if defined(__riscv) && (__riscv_xlen == 64)294# define SANITIZER_RISCV64 1295#else296# define SANITIZER_RISCV64 0297#endif298 299#if defined(__loongarch_lp64)300# define SANITIZER_LOONGARCH64 1301#else302# define SANITIZER_LOONGARCH64 0303#endif304 305// By default we allow to use SizeClassAllocator64 on 64-bit platform.306// But in some cases SizeClassAllocator64 does not work well and we need to307// fallback to SizeClassAllocator32.308// For such platforms build this code with -DSANITIZER_CAN_USE_ALLOCATOR64=0 or309// change the definition of SANITIZER_CAN_USE_ALLOCATOR64 here.310#ifndef SANITIZER_CAN_USE_ALLOCATOR64311# if (SANITIZER_RISCV64 && !SANITIZER_FUCHSIA && !SANITIZER_LINUX) || \312 SANITIZER_IOS || SANITIZER_DRIVERKIT313# define SANITIZER_CAN_USE_ALLOCATOR64 0314# elif defined(__mips64) || defined(__hexagon__)315# define SANITIZER_CAN_USE_ALLOCATOR64 0316# else317# define SANITIZER_CAN_USE_ALLOCATOR64 (SANITIZER_WORDSIZE == 64)318# endif319#endif320 321// The first address that can be returned by mmap.322#define SANITIZER_MMAP_BEGIN 0323 324// The range of addresses which can be returned my mmap.325// FIXME: this value should be different on different platforms. Larger values326// will still work but will consume more memory for TwoLevelByteMap.327#if defined(__mips__)328# if SANITIZER_GO && defined(__mips64)329# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 47)330# else331# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 40)332# endif333#elif SANITIZER_RISCV64334// FIXME: Rather than hardcoding the VMA here, we should rely on335// GetMaxUserVirtualAddress(). This will require some refactoring though since336// many places either hardcode some value or SANITIZER_MMAP_RANGE_SIZE is337// assumed to be some constant integer.338# if SANITIZER_FUCHSIA339# define SANITIZER_MMAP_RANGE_SIZE (1ULL << 38)340# else341# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 56)342# endif343#elif defined(__aarch64__)344# if SANITIZER_APPLE345# if SANITIZER_OSX || SANITIZER_IOSSIM346# define SANITIZER_MMAP_RANGE_SIZE \347 FIRST_32_SECOND_64(1ULL << 32, 1ULL << 47)348# else349// Darwin iOS/ARM64 has a 36-bit VMA, 64GiB VM350# define SANITIZER_MMAP_RANGE_SIZE \351 FIRST_32_SECOND_64(1ULL << 32, 1ULL << 36)352# endif353# else354# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 48)355# endif356#elif defined(__sparc__)357# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 52)358#else359# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 47)360#endif361 362// Whether the addresses are sign-extended from the VMA range to the word.363// The SPARC64 Linux port implements this to split the VMA space into two364// non-contiguous halves with a huge hole in the middle.365#if defined(__sparc__) && SANITIZER_WORDSIZE == 64366# define SANITIZER_SIGN_EXTENDED_ADDRESSES 1367#else368# define SANITIZER_SIGN_EXTENDED_ADDRESSES 0369#endif370 371// udi16 syscalls can only be used when the following conditions are372// met:373// * target is one of arm32, x86-32, sparc32, sh or m68k374// * libc version is libc5, glibc-2.0, glibc-2.1 or glibc-2.2 to 2.15375// built against > linux-2.2 kernel headers376// Since we don't want to include libc headers here, we check the377// target only.378#if defined(__arm__) || SANITIZER_X32 || defined(__sparc__)379# define SANITIZER_USES_UID16_SYSCALLS 1380#else381# define SANITIZER_USES_UID16_SYSCALLS 0382#endif383 384#if defined(__mips__)385# define SANITIZER_POINTER_FORMAT_LENGTH FIRST_32_SECOND_64(8, 10)386#else387# define SANITIZER_POINTER_FORMAT_LENGTH FIRST_32_SECOND_64(8, 12)388#endif389 390/// \macro MSC_PREREQ391/// \brief Is the compiler MSVC of at least the specified version?392/// The common \param version values to check for are:393/// * 1800: Microsoft Visual Studio 2013 / 12.0394/// * 1900: Microsoft Visual Studio 2015 / 14.0395#ifdef _MSC_VER396# define MSC_PREREQ(version) (_MSC_VER >= (version))397#else398# define MSC_PREREQ(version) 0399#endif400 401#if SANITIZER_APPLE && defined(__x86_64__)402# define SANITIZER_NON_UNIQUE_TYPEINFO 0403#else404# define SANITIZER_NON_UNIQUE_TYPEINFO 1405#endif406 407// On linux, some architectures had an ABI transition from 64-bit long double408// (ie. same as double) to 128-bit long double. On those, glibc symbols409// involving long doubles come in two versions, and we need to pass the410// correct one to dlvsym when intercepting them.411#if SANITIZER_LINUX && (SANITIZER_S390 || SANITIZER_PPC32 || SANITIZER_PPC64V1)412# define SANITIZER_NLDBL_VERSION "GLIBC_2.4"413#endif414 415#if SANITIZER_GO == 0416# define SANITIZER_GO 0417#endif418 419// On PowerPC and ARM Thumb, calling pthread_exit() causes LSan to detect leaks.420// pthread_exit() performs unwinding that leads to dlopen'ing libgcc_s.so.421// dlopen mallocs "libgcc_s.so" string which confuses LSan, it fails to realize422// that this allocation happens in dynamic linker and should be ignored.423#if SANITIZER_PPC || defined(__thumb__)424# define SANITIZER_SUPPRESS_LEAK_ON_PTHREAD_EXIT 1425#else426# define SANITIZER_SUPPRESS_LEAK_ON_PTHREAD_EXIT 0427#endif428 429#if SANITIZER_FREEBSD || SANITIZER_APPLE || SANITIZER_NETBSD || \430 SANITIZER_SOLARIS || SANITIZER_HAIKU431# define SANITIZER_MADVISE_DONTNEED MADV_FREE432#else433# define SANITIZER_MADVISE_DONTNEED MADV_DONTNEED434#endif435 436// Older gcc have issues aligning to a constexpr, and require an integer.437// See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56859 among others.438#if defined(__powerpc__) || defined(__powerpc64__)439# define SANITIZER_CACHE_LINE_SIZE 128440#else441# define SANITIZER_CACHE_LINE_SIZE 64442#endif443 444// Enable offline markup symbolizer for Fuchsia.445#if SANITIZER_FUCHSIA446# define SANITIZER_SYMBOLIZER_MARKUP 1447#else448# define SANITIZER_SYMBOLIZER_MARKUP 0449#endif450 451// Enable ability to support sanitizer initialization that is452// compatible with the sanitizer library being loaded via453// `dlopen()`.454#if SANITIZER_APPLE455# define SANITIZER_SUPPORTS_INIT_FOR_DLOPEN 1456#else457# define SANITIZER_SUPPORTS_INIT_FOR_DLOPEN 0458#endif459 460// SANITIZER_SUPPORTS_THREADLOCAL461// 1 - THREADLOCAL macro is supported by target462// 0 - THREADLOCAL macro is not supported by target463#ifndef __has_feature464// TODO: Support other compilers here465# define SANITIZER_SUPPORTS_THREADLOCAL 1466#else467# if __has_feature(tls)468# define SANITIZER_SUPPORTS_THREADLOCAL 1469# else470# define SANITIZER_SUPPORTS_THREADLOCAL 0471# endif472#endif473 474#if defined(__thumb__) && defined(__linux__)475// Workaround for476// https://lab.llvm.org/buildbot/#/builders/clang-thumbv7-full-2stage477// or478// https://lab.llvm.org/staging/#/builders/clang-thumbv7-full-2stage479// It fails *rss_limit_mb_test* without meaningful errors.480# define SANITIZER_START_BACKGROUND_THREAD_IN_ASAN_INTERNAL 1481#else482# define SANITIZER_START_BACKGROUND_THREAD_IN_ASAN_INTERNAL 0483#endif484 485#if SANITIZER_LINUX486# if SANITIZER_GLIBC487// Workaround for488// glibc/commit/3d3572f59059e2b19b8541ea648a6172136ec42e489// Linux: Keep termios ioctl constants strictly internal490# if __GLIBC_PREREQ(2, 41)491# define SANITIZER_TERMIOS_IOCTL_CONSTANTS 0492# else493# define SANITIZER_TERMIOS_IOCTL_CONSTANTS 1494# endif495# else496# define SANITIZER_TERMIOS_IOCTL_CONSTANTS 1497# endif498#endif499 500#if SANITIZER_APPLE && SANITIZER_WORDSIZE == 64501// MTE uses the lower half of the top byte.502# define STRIP_MTE_TAG(addr) ((addr) & ~((uptr)0x0f << 56))503#else504# define STRIP_MTE_TAG(addr) (addr)505#endif506 507#endif // SANITIZER_PLATFORM_H508