(root)/
gcc-13.2.0/
libsanitizer/
asan/
asan_mapping.h
       1  //===-- asan_mapping.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  // This file is a part of AddressSanitizer, an address sanity checker.
      10  //
      11  // Defines ASan memory mapping.
      12  //===----------------------------------------------------------------------===//
      13  #ifndef ASAN_MAPPING_H
      14  #define ASAN_MAPPING_H
      15  
      16  #include "sanitizer_common/sanitizer_platform.h"
      17  
      18  // The full explanation of the memory mapping could be found here:
      19  // https://github.com/google/sanitizers/wiki/AddressSanitizerAlgorithm
      20  //
      21  // Typical shadow mapping on Linux/x86_64 with SHADOW_OFFSET == 0x00007fff8000:
      22  // || `[0x10007fff8000, 0x7fffffffffff]` || HighMem    ||
      23  // || `[0x02008fff7000, 0x10007fff7fff]` || HighShadow ||
      24  // || `[0x00008fff7000, 0x02008fff6fff]` || ShadowGap  ||
      25  // || `[0x00007fff8000, 0x00008fff6fff]` || LowShadow  ||
      26  // || `[0x000000000000, 0x00007fff7fff]` || LowMem     ||
      27  //
      28  // When SHADOW_OFFSET is zero (-pie):
      29  // || `[0x100000000000, 0x7fffffffffff]` || HighMem    ||
      30  // || `[0x020000000000, 0x0fffffffffff]` || HighShadow ||
      31  // || `[0x000000040000, 0x01ffffffffff]` || ShadowGap  ||
      32  //
      33  // Special case when something is already mapped between
      34  // 0x003000000000 and 0x005000000000 (e.g. when prelink is installed):
      35  // || `[0x10007fff8000, 0x7fffffffffff]` || HighMem    ||
      36  // || `[0x02008fff7000, 0x10007fff7fff]` || HighShadow ||
      37  // || `[0x005000000000, 0x02008fff6fff]` || ShadowGap3 ||
      38  // || `[0x003000000000, 0x004fffffffff]` || MidMem     ||
      39  // || `[0x000a7fff8000, 0x002fffffffff]` || ShadowGap2 ||
      40  // || `[0x00067fff8000, 0x000a7fff7fff]` || MidShadow  ||
      41  // || `[0x00008fff7000, 0x00067fff7fff]` || ShadowGap  ||
      42  // || `[0x00007fff8000, 0x00008fff6fff]` || LowShadow  ||
      43  // || `[0x000000000000, 0x00007fff7fff]` || LowMem     ||
      44  //
      45  // Default Linux/i386 mapping on x86_64 machine:
      46  // || `[0x40000000, 0xffffffff]` || HighMem    ||
      47  // || `[0x28000000, 0x3fffffff]` || HighShadow ||
      48  // || `[0x24000000, 0x27ffffff]` || ShadowGap  ||
      49  // || `[0x20000000, 0x23ffffff]` || LowShadow  ||
      50  // || `[0x00000000, 0x1fffffff]` || LowMem     ||
      51  //
      52  // Default Linux/i386 mapping on i386 machine
      53  // (addresses starting with 0xc0000000 are reserved
      54  // for kernel and thus not sanitized):
      55  // || `[0x38000000, 0xbfffffff]` || HighMem    ||
      56  // || `[0x27000000, 0x37ffffff]` || HighShadow ||
      57  // || `[0x24000000, 0x26ffffff]` || ShadowGap  ||
      58  // || `[0x20000000, 0x23ffffff]` || LowShadow  ||
      59  // || `[0x00000000, 0x1fffffff]` || LowMem     ||
      60  //
      61  // Default Linux/MIPS32 mapping:
      62  // || `[0x2aaa0000, 0xffffffff]` || HighMem    ||
      63  // || `[0x0fff4000, 0x2aa9ffff]` || HighShadow ||
      64  // || `[0x0bff4000, 0x0fff3fff]` || ShadowGap  ||
      65  // || `[0x0aaa0000, 0x0bff3fff]` || LowShadow  ||
      66  // || `[0x00000000, 0x0aa9ffff]` || LowMem     ||
      67  //
      68  // Default Linux/MIPS64 mapping:
      69  // || `[0x4000000000, 0xffffffffff]` || HighMem    ||
      70  // || `[0x2800000000, 0x3fffffffff]` || HighShadow ||
      71  // || `[0x2400000000, 0x27ffffffff]` || ShadowGap  ||
      72  // || `[0x2000000000, 0x23ffffffff]` || LowShadow  ||
      73  // || `[0x0000000000, 0x1fffffffff]` || LowMem     ||
      74  //
      75  // Default Linux/RISCV64 Sv39 mapping:
      76  // || `[0x1555550000, 0x3fffffffff]` || HighMem    ||
      77  // || `[0x0fffffa000, 0x1555555fff]` || HighShadow ||
      78  // || `[0x0effffa000, 0x0fffff9fff]` || ShadowGap  ||
      79  // || `[0x0d55550000, 0x0effff9fff]` || LowShadow  ||
      80  // || `[0x0000000000, 0x0d5554ffff]` || LowMem     ||
      81  //
      82  // Default Linux/AArch64 (39-bit VMA) mapping:
      83  // || `[0x2000000000, 0x7fffffffff]` || highmem    ||
      84  // || `[0x1400000000, 0x1fffffffff]` || highshadow ||
      85  // || `[0x1200000000, 0x13ffffffff]` || shadowgap  ||
      86  // || `[0x1000000000, 0x11ffffffff]` || lowshadow  ||
      87  // || `[0x0000000000, 0x0fffffffff]` || lowmem     ||
      88  //
      89  // Default Linux/AArch64 (42-bit VMA) mapping:
      90  // || `[0x10000000000, 0x3ffffffffff]` || highmem    ||
      91  // || `[0x0a000000000, 0x0ffffffffff]` || highshadow ||
      92  // || `[0x09000000000, 0x09fffffffff]` || shadowgap  ||
      93  // || `[0x08000000000, 0x08fffffffff]` || lowshadow  ||
      94  // || `[0x00000000000, 0x07fffffffff]` || lowmem     ||
      95  //
      96  // Default Linux/S390 mapping:
      97  // || `[0x30000000, 0x7fffffff]` || HighMem    ||
      98  // || `[0x26000000, 0x2fffffff]` || HighShadow ||
      99  // || `[0x24000000, 0x25ffffff]` || ShadowGap  ||
     100  // || `[0x20000000, 0x23ffffff]` || LowShadow  ||
     101  // || `[0x00000000, 0x1fffffff]` || LowMem     ||
     102  //
     103  // Default Linux/SystemZ mapping:
     104  // || `[0x14000000000000, 0x1fffffffffffff]` || HighMem    ||
     105  // || `[0x12800000000000, 0x13ffffffffffff]` || HighShadow ||
     106  // || `[0x12000000000000, 0x127fffffffffff]` || ShadowGap  ||
     107  // || `[0x10000000000000, 0x11ffffffffffff]` || LowShadow  ||
     108  // || `[0x00000000000000, 0x0fffffffffffff]` || LowMem     ||
     109  //
     110  // Default Linux/SPARC64 (52-bit VMA) mapping:
     111  // || `[0x8000000000000, 0xfffffffffffff]` || HighMem    ||
     112  // || `[0x1080000000000, 0x207ffffffffff]` || HighShadow ||
     113  // || `[0x0090000000000, 0x107ffffffffff]` || ShadowGap  ||
     114  // || `[0x0080000000000, 0x008ffffffffff]` || LowShadow  ||
     115  // || `[0x0000000000000, 0x007ffffffffff]` || LowMem     ||
     116  //
     117  // Default Linux/LoongArch64 (47-bit VMA) mapping:
     118  // || `[0x500000000000, 0x7fffffffffff]` || HighMem    ||
     119  // || `[0x4a0000000000, 0x4fffffffffff]` || HighShadow ||
     120  // || `[0x480000000000, 0x49ffffffffff]` || ShadowGap  ||
     121  // || `[0x400000000000, 0x47ffffffffff]` || LowShadow  ||
     122  // || `[0x000000000000, 0x3fffffffffff]` || LowMem     ||
     123  //
     124  // Shadow mapping on FreeBSD/x86-64 with SHADOW_OFFSET == 0x400000000000:
     125  // || `[0x500000000000, 0x7fffffffffff]` || HighMem    ||
     126  // || `[0x4a0000000000, 0x4fffffffffff]` || HighShadow ||
     127  // || `[0x480000000000, 0x49ffffffffff]` || ShadowGap  ||
     128  // || `[0x400000000000, 0x47ffffffffff]` || LowShadow  ||
     129  // || `[0x000000000000, 0x3fffffffffff]` || LowMem     ||
     130  //
     131  // Shadow mapping on FreeBSD/i386 with SHADOW_OFFSET == 0x40000000:
     132  // || `[0x60000000, 0xffffffff]` || HighMem    ||
     133  // || `[0x4c000000, 0x5fffffff]` || HighShadow ||
     134  // || `[0x48000000, 0x4bffffff]` || ShadowGap  ||
     135  // || `[0x40000000, 0x47ffffff]` || LowShadow  ||
     136  // || `[0x00000000, 0x3fffffff]` || LowMem     ||
     137  //
     138  // Shadow mapping on NetBSD/x86-64 with SHADOW_OFFSET == 0x400000000000:
     139  // || `[0x4feffffffe01, 0x7f7ffffff000]` || HighMem    ||
     140  // || `[0x49fdffffffc0, 0x4feffffffe00]` || HighShadow ||
     141  // || `[0x480000000000, 0x49fdffffffbf]` || ShadowGap  ||
     142  // || `[0x400000000000, 0x47ffffffffff]` || LowShadow  ||
     143  // || `[0x000000000000, 0x3fffffffffff]` || LowMem     ||
     144  //
     145  // Shadow mapping on NetBSD/i386 with SHADOW_OFFSET == 0x40000000:
     146  // || `[0x60000000, 0xfffff000]` || HighMem    ||
     147  // || `[0x4c000000, 0x5fffffff]` || HighShadow ||
     148  // || `[0x48000000, 0x4bffffff]` || ShadowGap  ||
     149  // || `[0x40000000, 0x47ffffff]` || LowShadow  ||
     150  // || `[0x00000000, 0x3fffffff]` || LowMem     ||
     151  //
     152  // Default Windows/i386 mapping:
     153  // (the exact location of HighShadow/HighMem may vary depending
     154  //  on WoW64, /LARGEADDRESSAWARE, etc).
     155  // || `[0x50000000, 0xffffffff]` || HighMem    ||
     156  // || `[0x3a000000, 0x4fffffff]` || HighShadow ||
     157  // || `[0x36000000, 0x39ffffff]` || ShadowGap  ||
     158  // || `[0x30000000, 0x35ffffff]` || LowShadow  ||
     159  // || `[0x00000000, 0x2fffffff]` || LowMem     ||
     160  
     161  #define ASAN_SHADOW_SCALE 3
     162  
     163  #if SANITIZER_FUCHSIA
     164  #  define ASAN_SHADOW_OFFSET_CONST (0)
     165  #elif SANITIZER_WORDSIZE == 32
     166  #  if SANITIZER_ANDROID
     167  #    define ASAN_SHADOW_OFFSET_DYNAMIC
     168  #  elif defined(__mips__)
     169  #    define ASAN_SHADOW_OFFSET_CONST 0x0aaa0000
     170  #  elif SANITIZER_FREEBSD
     171  #    define ASAN_SHADOW_OFFSET_CONST 0x40000000
     172  #  elif SANITIZER_NETBSD
     173  #    define ASAN_SHADOW_OFFSET_CONST 0x40000000
     174  #  elif SANITIZER_WINDOWS
     175  #    define ASAN_SHADOW_OFFSET_CONST 0x30000000
     176  #  elif SANITIZER_IOS
     177  #    define ASAN_SHADOW_OFFSET_DYNAMIC
     178  #  else
     179  #    define ASAN_SHADOW_OFFSET_CONST 0x20000000
     180  #  endif
     181  #else
     182  #  if SANITIZER_IOS
     183  #    define ASAN_SHADOW_OFFSET_DYNAMIC
     184  #  elif SANITIZER_APPLE && defined(__aarch64__)
     185  #    define ASAN_SHADOW_OFFSET_DYNAMIC
     186  #  elif SANITIZER_FREEBSD && defined(__aarch64__)
     187  #    define ASAN_SHADOW_OFFSET_CONST 0x0000800000000000
     188  #  elif SANITIZER_RISCV64
     189  #    define ASAN_SHADOW_OFFSET_CONST 0x0000000d55550000
     190  #  elif defined(__aarch64__)
     191  #    define ASAN_SHADOW_OFFSET_CONST 0x0000001000000000
     192  #  elif defined(__powerpc64__)
     193  #    define ASAN_SHADOW_OFFSET_CONST 0x0000020000000000
     194  #  elif defined(__s390x__)
     195  #    define ASAN_SHADOW_OFFSET_CONST 0x0010000000000000
     196  #  elif SANITIZER_FREEBSD
     197  #    define ASAN_SHADOW_OFFSET_CONST 0x0000400000000000
     198  #  elif SANITIZER_NETBSD
     199  #    define ASAN_SHADOW_OFFSET_CONST 0x0000400000000000
     200  #  elif SANITIZER_APPLE
     201  #    define ASAN_SHADOW_OFFSET_CONST 0x0000100000000000
     202  #  elif defined(__mips64)
     203  #    define ASAN_SHADOW_OFFSET_CONST 0x0000002000000000
     204  #  elif defined(__sparc__)
     205  #    define ASAN_SHADOW_OFFSET_CONST 0x0000080000000000
     206  #  elif SANITIZER_LOONGARCH64
     207  #    define ASAN_SHADOW_OFFSET_CONST 0x0000400000000000
     208  #  elif SANITIZER_WINDOWS64
     209  #    define ASAN_SHADOW_OFFSET_DYNAMIC
     210  #  else
     211  #    if ASAN_SHADOW_SCALE != 3
     212  #      error "Value below is based on shadow scale = 3."
     213  #      error "Original formula was: 0x7FFFFFFF & (~0xFFFULL << SHADOW_SCALE)."
     214  #    endif
     215  #    define ASAN_SHADOW_OFFSET_CONST 0x000000007fff8000
     216  #  endif
     217  #endif
     218  
     219  #if defined(__cplusplus)
     220  #  include "asan_internal.h"
     221  
     222  static const u64 kDefaultShadowSentinel = ~(uptr)0;
     223  
     224  #  if defined(ASAN_SHADOW_OFFSET_CONST)
     225  static const u64 kConstShadowOffset = ASAN_SHADOW_OFFSET_CONST;
     226  #    define ASAN_SHADOW_OFFSET kConstShadowOffset
     227  #  elif defined(ASAN_SHADOW_OFFSET_DYNAMIC)
     228  #    define ASAN_SHADOW_OFFSET __asan_shadow_memory_dynamic_address
     229  #  else
     230  #    error "ASAN_SHADOW_OFFSET can't be determined."
     231  #  endif
     232  
     233  #  if SANITIZER_ANDROID && defined(__arm__)
     234  #    define ASAN_PREMAP_SHADOW 1
     235  #  else
     236  #    define ASAN_PREMAP_SHADOW 0
     237  #  endif
     238  
     239  #  define ASAN_SHADOW_GRANULARITY (1ULL << ASAN_SHADOW_SCALE)
     240  
     241  #  define DO_ASAN_MAPPING_PROFILE 0  // Set to 1 to profile the functions below.
     242  
     243  #  if DO_ASAN_MAPPING_PROFILE
     244  #    define PROFILE_ASAN_MAPPING() AsanMappingProfile[__LINE__]++;
     245  #  else
     246  #    define PROFILE_ASAN_MAPPING()
     247  #  endif
     248  
     249  // If 1, all shadow boundaries are constants.
     250  // Don't set to 1 other than for testing.
     251  #  define ASAN_FIXED_MAPPING 0
     252  
     253  namespace __asan {
     254  
     255  extern uptr AsanMappingProfile[];
     256  
     257  #  if ASAN_FIXED_MAPPING
     258  // Fixed mapping for 64-bit Linux. Mostly used for performance comparison
     259  // with non-fixed mapping. As of r175253 (Feb 2013) the performance
     260  // difference between fixed and non-fixed mapping is below the noise level.
     261  static uptr kHighMemEnd = 0x7fffffffffffULL;
     262  static uptr kMidMemBeg = 0x3000000000ULL;
     263  static uptr kMidMemEnd = 0x4fffffffffULL;
     264  #  else
     265  extern uptr kHighMemEnd, kMidMemBeg, kMidMemEnd;  // Initialized in __asan_init.
     266  #  endif
     267  
     268  }  // namespace __asan
     269  
     270  #  if defined(__sparc__) && SANITIZER_WORDSIZE == 64
     271  #    include "asan_mapping_sparc64.h"
     272  #  else
     273  #    define MEM_TO_SHADOW(mem) \
     274        (((mem) >> ASAN_SHADOW_SCALE) + (ASAN_SHADOW_OFFSET))
     275  #    define SHADOW_TO_MEM(mem) \
     276        (((mem) - (ASAN_SHADOW_OFFSET)) << (ASAN_SHADOW_SCALE))
     277  
     278  #    define kLowMemBeg 0
     279  #    define kLowMemEnd (ASAN_SHADOW_OFFSET ? ASAN_SHADOW_OFFSET - 1 : 0)
     280  
     281  #    define kLowShadowBeg ASAN_SHADOW_OFFSET
     282  #    define kLowShadowEnd MEM_TO_SHADOW(kLowMemEnd)
     283  
     284  #    define kHighMemBeg (MEM_TO_SHADOW(kHighMemEnd) + 1)
     285  
     286  #    define kHighShadowBeg MEM_TO_SHADOW(kHighMemBeg)
     287  #    define kHighShadowEnd MEM_TO_SHADOW(kHighMemEnd)
     288  
     289  #    define kMidShadowBeg MEM_TO_SHADOW(kMidMemBeg)
     290  #    define kMidShadowEnd MEM_TO_SHADOW(kMidMemEnd)
     291  
     292  // With the zero shadow base we can not actually map pages starting from 0.
     293  // This constant is somewhat arbitrary.
     294  #    define kZeroBaseShadowStart 0
     295  #    define kZeroBaseMaxShadowStart (1 << 18)
     296  
     297  #    define kShadowGapBeg \
     298        (kLowShadowEnd ? kLowShadowEnd + 1 : kZeroBaseShadowStart)
     299  #    define kShadowGapEnd ((kMidMemBeg ? kMidShadowBeg : kHighShadowBeg) - 1)
     300  
     301  #    define kShadowGap2Beg (kMidMemBeg ? kMidShadowEnd + 1 : 0)
     302  #    define kShadowGap2End (kMidMemBeg ? kMidMemBeg - 1 : 0)
     303  
     304  #    define kShadowGap3Beg (kMidMemBeg ? kMidMemEnd + 1 : 0)
     305  #    define kShadowGap3End (kMidMemBeg ? kHighShadowBeg - 1 : 0)
     306  
     307  namespace __asan {
     308  
     309  static inline bool AddrIsInLowMem(uptr a) {
     310    PROFILE_ASAN_MAPPING();
     311    return a <= kLowMemEnd;
     312  }
     313  
     314  static inline bool AddrIsInLowShadow(uptr a) {
     315    PROFILE_ASAN_MAPPING();
     316    return a >= kLowShadowBeg && a <= kLowShadowEnd;
     317  }
     318  
     319  static inline bool AddrIsInMidMem(uptr a) {
     320    PROFILE_ASAN_MAPPING();
     321    return kMidMemBeg && a >= kMidMemBeg && a <= kMidMemEnd;
     322  }
     323  
     324  static inline bool AddrIsInMidShadow(uptr a) {
     325    PROFILE_ASAN_MAPPING();
     326    return kMidMemBeg && a >= kMidShadowBeg && a <= kMidShadowEnd;
     327  }
     328  
     329  static inline bool AddrIsInHighMem(uptr a) {
     330    PROFILE_ASAN_MAPPING();
     331    return kHighMemBeg && a >= kHighMemBeg && a <= kHighMemEnd;
     332  }
     333  
     334  static inline bool AddrIsInHighShadow(uptr a) {
     335    PROFILE_ASAN_MAPPING();
     336    return kHighMemBeg && a >= kHighShadowBeg && a <= kHighShadowEnd;
     337  }
     338  
     339  static inline bool AddrIsInShadowGap(uptr a) {
     340    PROFILE_ASAN_MAPPING();
     341    if (kMidMemBeg) {
     342      if (a <= kShadowGapEnd)
     343        return ASAN_SHADOW_OFFSET == 0 || a >= kShadowGapBeg;
     344      return (a >= kShadowGap2Beg && a <= kShadowGap2End) ||
     345             (a >= kShadowGap3Beg && a <= kShadowGap3End);
     346    }
     347    // In zero-based shadow mode we treat addresses near zero as addresses
     348    // in shadow gap as well.
     349    if (ASAN_SHADOW_OFFSET == 0)
     350      return a <= kShadowGapEnd;
     351    return a >= kShadowGapBeg && a <= kShadowGapEnd;
     352  }
     353  
     354  }  // namespace __asan
     355  
     356  #  endif
     357  
     358  namespace __asan {
     359  
     360  static inline uptr MemToShadowSize(uptr size) {
     361    return size >> ASAN_SHADOW_SCALE;
     362  }
     363  
     364  static inline bool AddrIsInMem(uptr a) {
     365    PROFILE_ASAN_MAPPING();
     366    return AddrIsInLowMem(a) || AddrIsInMidMem(a) || AddrIsInHighMem(a) ||
     367           (flags()->protect_shadow_gap == 0 && AddrIsInShadowGap(a));
     368  }
     369  
     370  static inline uptr MemToShadow(uptr p) {
     371    PROFILE_ASAN_MAPPING();
     372    CHECK(AddrIsInMem(p));
     373    return MEM_TO_SHADOW(p);
     374  }
     375  
     376  static inline bool AddrIsInShadow(uptr a) {
     377    PROFILE_ASAN_MAPPING();
     378    return AddrIsInLowShadow(a) || AddrIsInMidShadow(a) || AddrIsInHighShadow(a);
     379  }
     380  
     381  static inline uptr ShadowToMem(uptr p) {
     382    PROFILE_ASAN_MAPPING();
     383    CHECK(AddrIsInShadow(p));
     384    return SHADOW_TO_MEM(p);
     385  }
     386  
     387  static inline bool AddrIsAlignedByGranularity(uptr a) {
     388    PROFILE_ASAN_MAPPING();
     389    return (a & (ASAN_SHADOW_GRANULARITY - 1)) == 0;
     390  }
     391  
     392  static inline bool AddressIsPoisoned(uptr a) {
     393    PROFILE_ASAN_MAPPING();
     394    const uptr kAccessSize = 1;
     395    u8 *shadow_address = (u8 *)MEM_TO_SHADOW(a);
     396    s8 shadow_value = *shadow_address;
     397    if (shadow_value) {
     398      u8 last_accessed_byte =
     399          (a & (ASAN_SHADOW_GRANULARITY - 1)) + kAccessSize - 1;
     400      return (last_accessed_byte >= shadow_value);
     401    }
     402    return false;
     403  }
     404  
     405  // Must be after all calls to PROFILE_ASAN_MAPPING().
     406  static const uptr kAsanMappingProfileSize = __LINE__;
     407  
     408  }  // namespace __asan
     409  
     410  #endif  // __cplusplus
     411  
     412  #endif  // ASAN_MAPPING_H