(root)/
gcc-13.2.0/
libsanitizer/
asan/
asan_mapping_sparc64.h
       1  //===-- asan_mapping_sparc64.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  // SPARC64-specific definitions for ASan memory mapping.
      12  //===----------------------------------------------------------------------===//
      13  #ifndef ASAN_MAPPING_SPARC64_H
      14  #define ASAN_MAPPING_SPARC64_H
      15  
      16  // This is tailored to the 52-bit VM layout on SPARC-T4 and later.
      17  // The VM space is split into two 51-bit halves at both ends: the low part
      18  // has all the bits above the 51st cleared, while the high part has them set.
      19  //   0xfff8000000000000 - 0xffffffffffffffff
      20  //   0x0000000000000000 - 0x0007ffffffffffff
      21  
      22  #define VMA_BITS 52
      23  #define HIGH_BITS (64 - VMA_BITS)
      24  
      25  // The idea is to chop the high bits before doing the scaling, so the two
      26  // parts become contiguous again and the usual scheme can be applied.
      27  
      28  #define MEM_TO_SHADOW(mem)                                       \
      29    ((((mem) << HIGH_BITS) >> (HIGH_BITS + (ASAN_SHADOW_SCALE))) + \
      30     (ASAN_SHADOW_OFFSET))
      31  #define SHADOW_TO_MEM(ptr) (__asan::ShadowToMemSparc64(ptr))
      32  
      33  #define kLowMemBeg 0
      34  #define kLowMemEnd (ASAN_SHADOW_OFFSET - 1)
      35  
      36  #define kLowShadowBeg ASAN_SHADOW_OFFSET
      37  #define kLowShadowEnd MEM_TO_SHADOW(kLowMemEnd)
      38  
      39  // But of course there is the huge hole between the high shadow memory,
      40  // which is in the low part, and the beginning of the high part.
      41  
      42  #define kHighMemBeg (-(1ULL << (VMA_BITS - 1)))
      43  
      44  #define kHighShadowBeg MEM_TO_SHADOW(kHighMemBeg)
      45  #define kHighShadowEnd MEM_TO_SHADOW(kHighMemEnd)
      46  
      47  #define kMidShadowBeg 0
      48  #define kMidShadowEnd 0
      49  
      50  // With the zero shadow base we can not actually map pages starting from 0.
      51  // This constant is somewhat arbitrary.
      52  #define kZeroBaseShadowStart 0
      53  #define kZeroBaseMaxShadowStart (1 << 18)
      54  
      55  #define kShadowGapBeg (kLowShadowEnd + 1)
      56  #define kShadowGapEnd (kHighShadowBeg - 1)
      57  
      58  #define kShadowGap2Beg 0
      59  #define kShadowGap2End 0
      60  
      61  #define kShadowGap3Beg 0
      62  #define kShadowGap3End 0
      63  
      64  namespace __asan {
      65  
      66  static inline bool AddrIsInLowMem(uptr a) {
      67    PROFILE_ASAN_MAPPING();
      68    return a <= kLowMemEnd;
      69  }
      70  
      71  static inline bool AddrIsInLowShadow(uptr a) {
      72    PROFILE_ASAN_MAPPING();
      73    return a >= kLowShadowBeg && a <= kLowShadowEnd;
      74  }
      75  
      76  static inline bool AddrIsInMidMem(uptr a) {
      77    PROFILE_ASAN_MAPPING();
      78    return false;
      79  }
      80  
      81  static inline bool AddrIsInMidShadow(uptr a) {
      82    PROFILE_ASAN_MAPPING();
      83    return false;
      84  }
      85  
      86  static inline bool AddrIsInHighMem(uptr a) {
      87    PROFILE_ASAN_MAPPING();
      88    return kHighMemBeg && a >= kHighMemBeg && a <= kHighMemEnd;
      89  }
      90  
      91  static inline bool AddrIsInHighShadow(uptr a) {
      92    PROFILE_ASAN_MAPPING();
      93    return kHighMemBeg && a >= kHighShadowBeg && a <= kHighShadowEnd;
      94  }
      95  
      96  static inline bool AddrIsInShadowGap(uptr a) {
      97    PROFILE_ASAN_MAPPING();
      98    return a >= kShadowGapBeg && a <= kShadowGapEnd;
      99  }
     100  
     101  static inline constexpr uptr ShadowToMemSparc64(uptr p) {
     102    PROFILE_ASAN_MAPPING();
     103    p -= ASAN_SHADOW_OFFSET;
     104    p <<= ASAN_SHADOW_SCALE;
     105    if (p >= 0x8000000000000) {
     106      p |= (~0ULL) << VMA_BITS;
     107    }
     108    return p;
     109  }
     110  
     111  static_assert(ShadowToMemSparc64(MEM_TO_SHADOW(0x0000000000000000)) ==
     112                0x0000000000000000);
     113  static_assert(ShadowToMemSparc64(MEM_TO_SHADOW(0xfff8000000000000)) ==
     114                0xfff8000000000000);
     115  // Gets aligned down.
     116  static_assert(ShadowToMemSparc64(MEM_TO_SHADOW(0x0007ffffffffffff)) ==
     117                0x0007fffffffffff8);
     118  
     119  }  // namespace __asan
     120  
     121  #endif  // ASAN_MAPPING_SPARC64_H