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 64namespace __asan { 65 66static inline bool AddrIsInLowMem(uptr a) { 67 PROFILE_ASAN_MAPPING(); 68 return a <= kLowMemEnd; 69} 70 71static inline bool AddrIsInLowShadow(uptr a) { 72 PROFILE_ASAN_MAPPING(); 73 return a >= kLowShadowBeg && a <= kLowShadowEnd; 74} 75 76static inline bool AddrIsInMidMem(uptr a) { 77 PROFILE_ASAN_MAPPING(); 78 return false; 79} 80 81static inline bool AddrIsInMidShadow(uptr a) { 82 PROFILE_ASAN_MAPPING(); 83 return false; 84} 85 86static inline bool AddrIsInHighMem(uptr a) { 87 PROFILE_ASAN_MAPPING(); 88 return kHighMemBeg && a >= kHighMemBeg && a <= kHighMemEnd; 89} 90 91static inline bool AddrIsInHighShadow(uptr a) { 92 PROFILE_ASAN_MAPPING(); 93 return kHighMemBeg && a >= kHighShadowBeg && a <= kHighShadowEnd; 94} 95 96static inline bool AddrIsInShadowGap(uptr a) { 97 PROFILE_ASAN_MAPPING(); 98 return a >= kShadowGapBeg && a <= kShadowGapEnd; 99} 100 101static 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 111static_assert(ShadowToMemSparc64(MEM_TO_SHADOW(0x0000000000000000)) == 112 0x0000000000000000); 113static_assert(ShadowToMemSparc64(MEM_TO_SHADOW(0xfff8000000000000)) == 114 0xfff8000000000000); 115// Gets aligned down. 116static_assert(ShadowToMemSparc64(MEM_TO_SHADOW(0x0007ffffffffffff)) == 117 0x0007fffffffffff8); 118 119} // namespace __asan 120 121#endif // ASAN_MAPPING_SPARC64_H 122