1 //===-- asan_mapping.h ------------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file is a part of AddressSanitizer, an address sanity checker. 11 // 12 // Defines ASan memory mapping. 13 //===----------------------------------------------------------------------===// 14 #ifndef ASAN_MAPPING_H 15 #define ASAN_MAPPING_H 16 17 #include "asan_internal.h" 18 19 // The full explanation of the memory mapping could be found here: 20 // http://code.google.com/p/address-sanitizer/wiki/AddressSanitizerAlgorithm 21 22 #if ASAN_FLEXIBLE_MAPPING_AND_OFFSET == 1 23 extern __attribute__((visibility("default"))) uptr __asan_mapping_scale; 24 extern __attribute__((visibility("default"))) uptr __asan_mapping_offset; 25 # define SHADOW_SCALE (__asan_mapping_scale) 26 # define SHADOW_OFFSET (__asan_mapping_offset) 27 #else 28 # if ASAN_ANDROID 29 # define SHADOW_SCALE (3) 30 # define SHADOW_OFFSET (0) 31 # else 32 # define SHADOW_SCALE (3) 33 # if __WORDSIZE == 32 34 # define SHADOW_OFFSET (1 << 29) 35 # else 36 # define SHADOW_OFFSET (1ULL << 44) 37 # endif 38 # endif 39 #endif // ASAN_FLEXIBLE_MAPPING_AND_OFFSET 40 41 #define SHADOW_GRANULARITY (1ULL << SHADOW_SCALE) 42 #define MEM_TO_SHADOW(mem) (((mem) >> SHADOW_SCALE) | (SHADOW_OFFSET)) 43 #define SHADOW_TO_MEM(shadow) (((shadow) - SHADOW_OFFSET) << SHADOW_SCALE) 44 45 #if __WORDSIZE == 64 46 static const uptr kHighMemEnd = 0x00007fffffffffffUL; 47 #else // __WORDSIZE == 32 48 static const uptr kHighMemEnd = 0xffffffff; 49 #endif // __WORDSIZE 50 51 52 #define kLowMemBeg 0 53 #define kLowMemEnd (SHADOW_OFFSET ? SHADOW_OFFSET - 1 : 0) 54 55 #define kLowShadowBeg SHADOW_OFFSET 56 #define kLowShadowEnd MEM_TO_SHADOW(kLowMemEnd) 57 58 #define kHighMemBeg (MEM_TO_SHADOW(kHighMemEnd) + 1) 59 60 #define kHighShadowBeg MEM_TO_SHADOW(kHighMemBeg) 61 #define kHighShadowEnd MEM_TO_SHADOW(kHighMemEnd) 62 63 #define kShadowGapBeg (kLowShadowEnd ? kLowShadowEnd + 1 : 16 * kPageSize) 64 #define kShadowGapEnd (kHighShadowBeg - 1) 65 66 #define kGlobalAndStackRedzone \ 67 (SHADOW_GRANULARITY < 32 ? 32 : SHADOW_GRANULARITY) 68 69 namespace __asan { 70 AddrIsInLowMem(uptr a)71static inline bool AddrIsInLowMem(uptr a) { 72 return a < kLowMemEnd; 73 } 74 AddrIsInLowShadow(uptr a)75static inline bool AddrIsInLowShadow(uptr a) { 76 return a >= kLowShadowBeg && a <= kLowShadowEnd; 77 } 78 AddrIsInHighMem(uptr a)79static inline bool AddrIsInHighMem(uptr a) { 80 return a >= kHighMemBeg && a <= kHighMemEnd; 81 } 82 AddrIsInMem(uptr a)83static inline bool AddrIsInMem(uptr a) { 84 return AddrIsInLowMem(a) || AddrIsInHighMem(a); 85 } 86 MemToShadow(uptr p)87static inline uptr MemToShadow(uptr p) { 88 CHECK(AddrIsInMem(p)); 89 return MEM_TO_SHADOW(p); 90 } 91 AddrIsInHighShadow(uptr a)92static inline bool AddrIsInHighShadow(uptr a) { 93 return a >= kHighShadowBeg && a <= kHighMemEnd; 94 } 95 AddrIsInShadow(uptr a)96static inline bool AddrIsInShadow(uptr a) { 97 return AddrIsInLowShadow(a) || AddrIsInHighShadow(a); 98 } 99 AddrIsInShadowGap(uptr a)100static inline bool AddrIsInShadowGap(uptr a) { 101 return a >= kShadowGapBeg && a <= kShadowGapEnd; 102 } 103 AddrIsAlignedByGranularity(uptr a)104static inline bool AddrIsAlignedByGranularity(uptr a) { 105 return (a & (SHADOW_GRANULARITY - 1)) == 0; 106 } 107 AddressIsPoisoned(uptr a)108static inline bool AddressIsPoisoned(uptr a) { 109 const uptr kAccessSize = 1; 110 u8 *shadow_address = (u8*)MemToShadow(a); 111 s8 shadow_value = *shadow_address; 112 if (shadow_value) { 113 u8 last_accessed_byte = (a & (SHADOW_GRANULARITY - 1)) 114 + kAccessSize - 1; 115 return (last_accessed_byte >= shadow_value); 116 } 117 return false; 118 } 119 120 } // namespace __asan 121 122 #endif // ASAN_MAPPING_H 123