11e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//===-- asan_mapping.h ------------------------------------------*- C++ -*-===//
21e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//
31e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//                     The LLVM Compiler Infrastructure
41e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//
51e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// This file is distributed under the University of Illinois Open Source
61e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// License. See LICENSE.TXT for details.
71e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//
81e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//===----------------------------------------------------------------------===//
91e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//
101e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// This file is a part of AddressSanitizer, an address sanity checker.
111e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//
121e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// Defines ASan memory mapping.
131e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//===----------------------------------------------------------------------===//
141e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#ifndef ASAN_MAPPING_H
151e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#define ASAN_MAPPING_H
161e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
171e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_internal.h"
181e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
191e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// The full explanation of the memory mapping could be found here:
201e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// http://code.google.com/p/address-sanitizer/wiki/AddressSanitizerAlgorithm
21e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany//
22e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany// Typical shadow mapping on Linux/x86_64 with SHADOW_OFFSET == 0x00007fff8000:
23e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany// || `[0x10007fff8000, 0x7fffffffffff]` || HighMem    ||
24e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany// || `[0x02008fff7000, 0x10007fff7fff]` || HighShadow ||
25e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany// || `[0x00008fff7000, 0x02008fff6fff]` || ShadowGap  ||
26e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany// || `[0x00007fff8000, 0x00008fff6fff]` || LowShadow  ||
27e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany// || `[0x000000000000, 0x00007fff7fff]` || LowMem     ||
28e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany//
29e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany// When SHADOW_OFFSET is zero (-pie):
30e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany// || `[0x100000000000, 0x7fffffffffff]` || HighMem    ||
31e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany// || `[0x020000000000, 0x0fffffffffff]` || HighShadow ||
32e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany// || `[0x000000040000, 0x01ffffffffff]` || ShadowGap  ||
33e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany//
34e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany// Special case when something is already mapped between
3513577fed9ac2ebe5e4800b8f83e3a80832907de2Kostya Serebryany// 0x003000000000 and 0x005000000000 (e.g. when prelink is installed):
36e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany// || `[0x10007fff8000, 0x7fffffffffff]` || HighMem    ||
37e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany// || `[0x02008fff7000, 0x10007fff7fff]` || HighShadow ||
3813577fed9ac2ebe5e4800b8f83e3a80832907de2Kostya Serebryany// || `[0x005000000000, 0x02008fff6fff]` || ShadowGap3 ||
3913577fed9ac2ebe5e4800b8f83e3a80832907de2Kostya Serebryany// || `[0x003000000000, 0x004fffffffff]` || MidMem     ||
4013577fed9ac2ebe5e4800b8f83e3a80832907de2Kostya Serebryany// || `[0x000a7fff8000, 0x002fffffffff]` || ShadowGap2 ||
4113577fed9ac2ebe5e4800b8f83e3a80832907de2Kostya Serebryany// || `[0x00067fff8000, 0x000a7fff7fff]` || MidShadow  ||
42e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany// || `[0x00008fff7000, 0x00067fff7fff]` || ShadowGap  ||
43e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany// || `[0x00007fff8000, 0x00008fff6fff]` || LowShadow  ||
44e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany// || `[0x000000000000, 0x00007fff7fff]` || LowMem     ||
45e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany//
462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// Default Linux/i386 mapping on x86_64 machine:
47e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany// || `[0x40000000, 0xffffffff]` || HighMem    ||
48e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany// || `[0x28000000, 0x3fffffff]` || HighShadow ||
49e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany// || `[0x24000000, 0x27ffffff]` || ShadowGap  ||
50e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany// || `[0x20000000, 0x23ffffff]` || LowShadow  ||
51e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany// || `[0x00000000, 0x1fffffff]` || LowMem     ||
5240527a579131210fcfa2373620a0c2200800e7c4Kostya Serebryany//
532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// Default Linux/i386 mapping on i386 machine
542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// (addresses starting with 0xc0000000 are reserved
552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// for kernel and thus not sanitized):
562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// || `[0x38000000, 0xbfffffff]` || HighMem    ||
572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// || `[0x27000000, 0x37ffffff]` || HighShadow ||
582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// || `[0x24000000, 0x26ffffff]` || ShadowGap  ||
592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// || `[0x20000000, 0x23ffffff]` || LowShadow  ||
602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// || `[0x00000000, 0x1fffffff]` || LowMem     ||
612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines//
6240527a579131210fcfa2373620a0c2200800e7c4Kostya Serebryany// Default Linux/MIPS mapping:
6340527a579131210fcfa2373620a0c2200800e7c4Kostya Serebryany// || `[0x2aaa8000, 0xffffffff]` || HighMem    ||
6440527a579131210fcfa2373620a0c2200800e7c4Kostya Serebryany// || `[0x0fffd000, 0x2aaa7fff]` || HighShadow ||
6540527a579131210fcfa2373620a0c2200800e7c4Kostya Serebryany// || `[0x0bffd000, 0x0fffcfff]` || ShadowGap  ||
6640527a579131210fcfa2373620a0c2200800e7c4Kostya Serebryany// || `[0x0aaa8000, 0x0bffcfff]` || LowShadow  ||
6740527a579131210fcfa2373620a0c2200800e7c4Kostya Serebryany// || `[0x00000000, 0x0aaa7fff]` || LowMem     ||
682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines//
692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// Shadow mapping on FreeBSD/x86-64 with SHADOW_OFFSET == 0x400000000000:
702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// || `[0x500000000000, 0x7fffffffffff]` || HighMem    ||
712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// || `[0x4a0000000000, 0x4fffffffffff]` || HighShadow ||
722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// || `[0x480000000000, 0x49ffffffffff]` || ShadowGap  ||
732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// || `[0x400000000000, 0x47ffffffffff]` || LowShadow  ||
742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// || `[0x000000000000, 0x3fffffffffff]` || LowMem     ||
752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines//
762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// Shadow mapping on FreeBSD/i386 with SHADOW_OFFSET == 0x40000000:
772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// || `[0x60000000, 0xffffffff]` || HighMem    ||
782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// || `[0x4c000000, 0x5fffffff]` || HighShadow ||
792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// || `[0x48000000, 0x4bffffff]` || ShadowGap  ||
802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// || `[0x40000000, 0x47ffffff]` || LowShadow  ||
812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// || `[0x00000000, 0x3fffffff]` || LowMem     ||
821e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
8322e21b044c9337a2fa921f268b7d221c693ad78bAlexey Samsonovstatic const u64 kDefaultShadowScale = 3;
842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic const u64 kDefaultShadowOffset32 = 1ULL << 29;  // 0x20000000
852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic const u64 kIosShadowOffset32 = 1ULL << 30;  // 0x40000000
8622e21b044c9337a2fa921f268b7d221c693ad78bAlexey Samsonovstatic const u64 kDefaultShadowOffset64 = 1ULL << 44;
8722e21b044c9337a2fa921f268b7d221c693ad78bAlexey Samsonovstatic const u64 kDefaultShort64bitShadowOffset = 0x7FFF8000;  // < 2G.
882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic const u64 kAArch64_ShadowOffset64 = 1ULL << 36;
8922e21b044c9337a2fa921f268b7d221c693ad78bAlexey Samsonovstatic const u64 kMIPS32_ShadowOffset32 = 0x0aaa8000;
905d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hinesstatic const u64 kPPC64_ShadowOffset64 = 1ULL << 41;
912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic const u64 kFreeBSD_ShadowOffset32 = 1ULL << 30;  // 0x40000000
922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic const u64 kFreeBSD_ShadowOffset64 = 1ULL << 46;  // 0x400000000000
9322e21b044c9337a2fa921f268b7d221c693ad78bAlexey Samsonov
942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define SHADOW_SCALE kDefaultShadowScale
952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_ANDROID
962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines# define SHADOW_OFFSET (0)
971e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#else
982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines# if SANITIZER_WORDSIZE == 32
992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#  if defined(__mips__)
1002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#    define SHADOW_OFFSET kMIPS32_ShadowOffset32
1012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#  elif SANITIZER_FREEBSD
1022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#    define SHADOW_OFFSET kFreeBSD_ShadowOffset32
1032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#  else
1042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#    if SANITIZER_IOS
1052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#      define SHADOW_OFFSET kIosShadowOffset32
1062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#    else
1072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#      define SHADOW_OFFSET kDefaultShadowOffset32
1082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#    endif
1092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#  endif
110f1ee2cd5e4c7a46e1188315daa2c79181f852becEvgeniy Stepanov# else
1112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#  if defined(__aarch64__)
1122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#    define SHADOW_OFFSET kAArch64_ShadowOffset64
1135d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#  elif defined(__powerpc64__)
1145d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#    define SHADOW_OFFSET kPPC64_ShadowOffset64
1152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#  elif SANITIZER_FREEBSD
1162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#    define SHADOW_OFFSET kFreeBSD_ShadowOffset64
1172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#  elif SANITIZER_MAC
1182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#   define SHADOW_OFFSET kDefaultShadowOffset64
119f1ee2cd5e4c7a46e1188315daa2c79181f852becEvgeniy Stepanov#  else
1202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#   define SHADOW_OFFSET kDefaultShort64bitShadowOffset
121f1ee2cd5e4c7a46e1188315daa2c79181f852becEvgeniy Stepanov#  endif
122f1ee2cd5e4c7a46e1188315daa2c79181f852becEvgeniy Stepanov# endif
1232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
1241e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
1251e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#define SHADOW_GRANULARITY (1ULL << SHADOW_SCALE)
126e5ab9688b623a5a0150c7eae1ec1caaf06d44758Kostya Serebryany#define MEM_TO_SHADOW(mem) (((mem) >> SHADOW_SCALE) + (SHADOW_OFFSET))
1273972ea03aa52d81ca324945ba94eea22d403df12Evgeniy Stepanov#define SHADOW_TO_MEM(shadow) (((shadow) - SHADOW_OFFSET) << SHADOW_SCALE)
1281e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
1291e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#define kLowMemBeg      0
1301e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#define kLowMemEnd      (SHADOW_OFFSET ? SHADOW_OFFSET - 1 : 0)
1311e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
1321e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#define kLowShadowBeg   SHADOW_OFFSET
1331e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#define kLowShadowEnd   MEM_TO_SHADOW(kLowMemEnd)
1341e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
1351e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#define kHighMemBeg     (MEM_TO_SHADOW(kHighMemEnd) + 1)
1361e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
1371e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#define kHighShadowBeg  MEM_TO_SHADOW(kHighMemBeg)
1381e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#define kHighShadowEnd  MEM_TO_SHADOW(kHighMemEnd)
1391e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
140e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany# define kMidShadowBeg MEM_TO_SHADOW(kMidMemBeg)
141e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany# define kMidShadowEnd MEM_TO_SHADOW(kMidMemEnd)
142e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany
143e89f1846d58550f919a0ef9081b11d4b0405019dKostya Serebryany// With the zero shadow base we can not actually map pages starting from 0.
144e89f1846d58550f919a0ef9081b11d4b0405019dKostya Serebryany// This constant is somewhat arbitrary.
145e89f1846d58550f919a0ef9081b11d4b0405019dKostya Serebryany#define kZeroBaseShadowStart (1 << 18)
146e89f1846d58550f919a0ef9081b11d4b0405019dKostya Serebryany
147e89f1846d58550f919a0ef9081b11d4b0405019dKostya Serebryany#define kShadowGapBeg   (kLowShadowEnd ? kLowShadowEnd + 1 \
148e89f1846d58550f919a0ef9081b11d4b0405019dKostya Serebryany                                       : kZeroBaseShadowStart)
149e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany#define kShadowGapEnd   ((kMidMemBeg ? kMidShadowBeg : kHighShadowBeg) - 1)
150e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany
151e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany#define kShadowGap2Beg (kMidMemBeg ? kMidShadowEnd + 1 : 0)
152e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany#define kShadowGap2End (kMidMemBeg ? kMidMemBeg - 1 : 0)
153e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany
154e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany#define kShadowGap3Beg (kMidMemBeg ? kMidMemEnd + 1 : 0)
155e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany#define kShadowGap3End (kMidMemBeg ? kHighShadowBeg - 1 : 0)
156e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany
157e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany#define DO_ASAN_MAPPING_PROFILE 0  // Set to 1 to profile the functions below.
158e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany
159e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany#if DO_ASAN_MAPPING_PROFILE
160e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany# define PROFILE_ASAN_MAPPING() AsanMappingProfile[__LINE__]++;
161e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany#else
162e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany# define PROFILE_ASAN_MAPPING()
163e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany#endif
164e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany
165e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany// If 1, all shadow boundaries are constants.
166e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany// Don't set to 1 other than for testing.
167e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany#define ASAN_FIXED_MAPPING 0
1681e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
1691e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanynamespace __asan {
1701e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
171e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryanyextern uptr AsanMappingProfile[];
172e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany
173e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany#if ASAN_FIXED_MAPPING
174e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany// Fixed mapping for 64-bit Linux. Mostly used for performance comparison
175e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany// with non-fixed mapping. As of r175253 (Feb 2013) the performance
176e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany// difference between fixed and non-fixed mapping is below the noise level.
177e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryanystatic uptr kHighMemEnd = 0x7fffffffffffULL;
178e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryanystatic uptr kMidMemBeg =    0x3000000000ULL;
17913577fed9ac2ebe5e4800b8f83e3a80832907de2Kostya Serebryanystatic uptr kMidMemEnd =    0x4fffffffffULL;
180e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany#else
181e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryanyextern uptr kHighMemEnd, kMidMemBeg, kMidMemEnd;  // Initialized in __asan_init.
182e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany#endif
183e5ab9688b623a5a0150c7eae1ec1caaf06d44758Kostya Serebryany
1843f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryanystatic inline bool AddrIsInLowMem(uptr a) {
185e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany  PROFILE_ASAN_MAPPING();
1861e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  return a < kLowMemEnd;
1871e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
1881e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
1893f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryanystatic inline bool AddrIsInLowShadow(uptr a) {
190e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany  PROFILE_ASAN_MAPPING();
1911e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  return a >= kLowShadowBeg && a <= kLowShadowEnd;
1921e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
1931e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
1943f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryanystatic inline bool AddrIsInHighMem(uptr a) {
195e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany  PROFILE_ASAN_MAPPING();
1961e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  return a >= kHighMemBeg && a <= kHighMemEnd;
1971e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
1981e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
199e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryanystatic inline bool AddrIsInMidMem(uptr a) {
200e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany  PROFILE_ASAN_MAPPING();
201e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany  return kMidMemBeg && a >= kMidMemBeg && a <= kMidMemEnd;
202e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany}
203e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany
2043f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryanystatic inline bool AddrIsInMem(uptr a) {
205e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany  PROFILE_ASAN_MAPPING();
206e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany  return AddrIsInLowMem(a) || AddrIsInMidMem(a) || AddrIsInHighMem(a);
2071e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
2081e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
2093f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryanystatic inline uptr MemToShadow(uptr p) {
210e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany  PROFILE_ASAN_MAPPING();
2111e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  CHECK(AddrIsInMem(p));
2121e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  return MEM_TO_SHADOW(p);
2131e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
2141e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
2153f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryanystatic inline bool AddrIsInHighShadow(uptr a) {
216e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany  PROFILE_ASAN_MAPPING();
217e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany  return a >= kHighShadowBeg && a <= kHighMemEnd;
218e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany}
219e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany
220e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryanystatic inline bool AddrIsInMidShadow(uptr a) {
221e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany  PROFILE_ASAN_MAPPING();
222e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany  return kMidMemBeg && a >= kMidShadowBeg && a <= kMidMemEnd;
2231e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
2241e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
2253f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryanystatic inline bool AddrIsInShadow(uptr a) {
226e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany  PROFILE_ASAN_MAPPING();
227e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany  return AddrIsInLowShadow(a) || AddrIsInMidShadow(a) || AddrIsInHighShadow(a);
2281e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
2291e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
23079d12e87fbcc1b2342d76367b99b83adf9cbf499Alexander Potapenkostatic inline bool AddrIsInShadowGap(uptr a) {
231e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany  PROFILE_ASAN_MAPPING();
232e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany  if (kMidMemBeg) {
233e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany    if (a <= kShadowGapEnd)
234e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany      return SHADOW_OFFSET == 0 || a >= kShadowGapBeg;
235e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany    return (a >= kShadowGap2Beg && a <= kShadowGap2End) ||
236e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany           (a >= kShadowGap3Beg && a <= kShadowGap3End);
237e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany  }
238ee485d42c43635f874e3197f636280a6b0f8c545Alexey Samsonov  // In zero-based shadow mode we treat addresses near zero as addresses
239ee485d42c43635f874e3197f636280a6b0f8c545Alexey Samsonov  // in shadow gap as well.
24087b52b910037447eccb92546b24b5e06181a1545Alexey Samsonov  if (SHADOW_OFFSET == 0)
241ee485d42c43635f874e3197f636280a6b0f8c545Alexey Samsonov    return a <= kShadowGapEnd;
24279d12e87fbcc1b2342d76367b99b83adf9cbf499Alexander Potapenko  return a >= kShadowGapBeg && a <= kShadowGapEnd;
24379d12e87fbcc1b2342d76367b99b83adf9cbf499Alexander Potapenko}
24479d12e87fbcc1b2342d76367b99b83adf9cbf499Alexander Potapenko
2453f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryanystatic inline bool AddrIsAlignedByGranularity(uptr a) {
246e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany  PROFILE_ASAN_MAPPING();
247218a9b70d7338cf5b727b7dad6b080ad7869c6c2Kostya Serebryany  return (a & (SHADOW_GRANULARITY - 1)) == 0;
248218a9b70d7338cf5b727b7dad6b080ad7869c6c2Kostya Serebryany}
249218a9b70d7338cf5b727b7dad6b080ad7869c6c2Kostya Serebryany
2503f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryanystatic inline bool AddressIsPoisoned(uptr a) {
251e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany  PROFILE_ASAN_MAPPING();
2523f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany  const uptr kAccessSize = 1;
253a84805f1ccb2b7d4b6c0ba384bd3541fa4eaf808Kostya Serebryany  u8 *shadow_address = (u8*)MEM_TO_SHADOW(a);
254ee3925515e4c7966f3ef489f687aa7e5692806a9Kostya Serebryany  s8 shadow_value = *shadow_address;
2558599762021935ccfce4db9b054f092af8ef001abKostya Serebryany  if (shadow_value) {
256ee3925515e4c7966f3ef489f687aa7e5692806a9Kostya Serebryany    u8 last_accessed_byte = (a & (SHADOW_GRANULARITY - 1))
2578599762021935ccfce4db9b054f092af8ef001abKostya Serebryany                                 + kAccessSize - 1;
2588599762021935ccfce4db9b054f092af8ef001abKostya Serebryany    return (last_accessed_byte >= shadow_value);
2598599762021935ccfce4db9b054f092af8ef001abKostya Serebryany  }
2608599762021935ccfce4db9b054f092af8ef001abKostya Serebryany  return false;
2618599762021935ccfce4db9b054f092af8ef001abKostya Serebryany}
2628599762021935ccfce4db9b054f092af8ef001abKostya Serebryany
263e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany// Must be after all calls to PROFILE_ASAN_MAPPING().
264e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryanystatic const uptr kAsanMappingProfileSize = __LINE__;
265e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany
2661e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}  // namespace __asan
2671e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
2681e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#endif  // ASAN_MAPPING_H
269