1229109Sed//===-- asan_mapping.h ------------------------------------------*- C++ -*-===//
2229109Sed//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6229109Sed//
7229109Sed//===----------------------------------------------------------------------===//
8229109Sed//
9229109Sed// This file is a part of AddressSanitizer, an address sanity checker.
10229109Sed//
11229109Sed// Defines ASan memory mapping.
12229109Sed//===----------------------------------------------------------------------===//
13229109Sed#ifndef ASAN_MAPPING_H
14229109Sed#define ASAN_MAPPING_H
15229109Sed
16229109Sed#include "asan_internal.h"
17229109Sed
18229109Sed// The full explanation of the memory mapping could be found here:
19296417Sdim// https://github.com/google/sanitizers/wiki/AddressSanitizerAlgorithm
20251034Sed//
21251034Sed// Typical shadow mapping on Linux/x86_64 with SHADOW_OFFSET == 0x00007fff8000:
22251034Sed// || `[0x10007fff8000, 0x7fffffffffff]` || HighMem    ||
23251034Sed// || `[0x02008fff7000, 0x10007fff7fff]` || HighShadow ||
24251034Sed// || `[0x00008fff7000, 0x02008fff6fff]` || ShadowGap  ||
25251034Sed// || `[0x00007fff8000, 0x00008fff6fff]` || LowShadow  ||
26251034Sed// || `[0x000000000000, 0x00007fff7fff]` || LowMem     ||
27251034Sed//
28251034Sed// When SHADOW_OFFSET is zero (-pie):
29251034Sed// || `[0x100000000000, 0x7fffffffffff]` || HighMem    ||
30251034Sed// || `[0x020000000000, 0x0fffffffffff]` || HighShadow ||
31251034Sed// || `[0x000000040000, 0x01ffffffffff]` || ShadowGap  ||
32251034Sed//
33251034Sed// Special case when something is already mapped between
34251034Sed// 0x003000000000 and 0x005000000000 (e.g. when prelink is installed):
35251034Sed// || `[0x10007fff8000, 0x7fffffffffff]` || HighMem    ||
36251034Sed// || `[0x02008fff7000, 0x10007fff7fff]` || HighShadow ||
37251034Sed// || `[0x005000000000, 0x02008fff6fff]` || ShadowGap3 ||
38251034Sed// || `[0x003000000000, 0x004fffffffff]` || MidMem     ||
39251034Sed// || `[0x000a7fff8000, 0x002fffffffff]` || ShadowGap2 ||
40251034Sed// || `[0x00067fff8000, 0x000a7fff7fff]` || MidShadow  ||
41251034Sed// || `[0x00008fff7000, 0x00067fff7fff]` || ShadowGap  ||
42251034Sed// || `[0x00007fff8000, 0x00008fff6fff]` || LowShadow  ||
43251034Sed// || `[0x000000000000, 0x00007fff7fff]` || LowMem     ||
44251034Sed//
45276789Sdim// Default Linux/i386 mapping on x86_64 machine:
46251034Sed// || `[0x40000000, 0xffffffff]` || HighMem    ||
47251034Sed// || `[0x28000000, 0x3fffffff]` || HighShadow ||
48251034Sed// || `[0x24000000, 0x27ffffff]` || ShadowGap  ||
49251034Sed// || `[0x20000000, 0x23ffffff]` || LowShadow  ||
50251034Sed// || `[0x00000000, 0x1fffffff]` || LowMem     ||
51274201Sdim//
52276789Sdim// Default Linux/i386 mapping on i386 machine
53276789Sdim// (addresses starting with 0xc0000000 are reserved
54276789Sdim// for kernel and thus not sanitized):
55276789Sdim// || `[0x38000000, 0xbfffffff]` || HighMem    ||
56276789Sdim// || `[0x27000000, 0x37ffffff]` || HighShadow ||
57276789Sdim// || `[0x24000000, 0x26ffffff]` || ShadowGap  ||
58276789Sdim// || `[0x20000000, 0x23ffffff]` || LowShadow  ||
59276789Sdim// || `[0x00000000, 0x1fffffff]` || LowMem     ||
60276789Sdim//
61280031Sdim// Default Linux/MIPS32 mapping:
62276789Sdim// || `[0x2aaa0000, 0xffffffff]` || HighMem    ||
63276789Sdim// || `[0x0fff4000, 0x2aa9ffff]` || HighShadow ||
64276789Sdim// || `[0x0bff4000, 0x0fff3fff]` || ShadowGap  ||
65276789Sdim// || `[0x0aaa0000, 0x0bff3fff]` || LowShadow  ||
66276789Sdim// || `[0x00000000, 0x0aa9ffff]` || LowMem     ||
67276789Sdim//
68280031Sdim// Default Linux/MIPS64 mapping:
69280031Sdim// || `[0x4000000000, 0xffffffffff]` || HighMem    ||
70280031Sdim// || `[0x2800000000, 0x3fffffffff]` || HighShadow ||
71280031Sdim// || `[0x2400000000, 0x27ffffffff]` || ShadowGap  ||
72280031Sdim// || `[0x2000000000, 0x23ffffffff]` || LowShadow  ||
73280031Sdim// || `[0x0000000000, 0x1fffffffff]` || LowMem     ||
74280031Sdim//
75296417Sdim// Default Linux/AArch64 (39-bit VMA) mapping:
76296417Sdim// || `[0x2000000000, 0x7fffffffff]` || highmem    ||
77296417Sdim// || `[0x1400000000, 0x1fffffffff]` || highshadow ||
78296417Sdim// || `[0x1200000000, 0x13ffffffff]` || shadowgap  ||
79296417Sdim// || `[0x1000000000, 0x11ffffffff]` || lowshadow  ||
80296417Sdim// || `[0x0000000000, 0x0fffffffff]` || lowmem     ||
81296417Sdim//
82296417Sdim// Default Linux/AArch64 (42-bit VMA) mapping:
83296417Sdim// || `[0x10000000000, 0x3ffffffffff]` || highmem    ||
84296417Sdim// || `[0x0a000000000, 0x0ffffffffff]` || highshadow ||
85296417Sdim// || `[0x09000000000, 0x09fffffffff]` || shadowgap  ||
86296417Sdim// || `[0x08000000000, 0x08fffffffff]` || lowshadow  ||
87296417Sdim// || `[0x00000000000, 0x07fffffffff]` || lowmem     ||
88296417Sdim//
89309124Sdim// Default Linux/S390 mapping:
90309124Sdim// || `[0x30000000, 0x7fffffff]` || HighMem    ||
91309124Sdim// || `[0x26000000, 0x2fffffff]` || HighShadow ||
92309124Sdim// || `[0x24000000, 0x25ffffff]` || ShadowGap  ||
93309124Sdim// || `[0x20000000, 0x23ffffff]` || LowShadow  ||
94309124Sdim// || `[0x00000000, 0x1fffffff]` || LowMem     ||
95309124Sdim//
96309124Sdim// Default Linux/SystemZ mapping:
97309124Sdim// || `[0x14000000000000, 0x1fffffffffffff]` || HighMem    ||
98309124Sdim// || `[0x12800000000000, 0x13ffffffffffff]` || HighShadow ||
99309124Sdim// || `[0x12000000000000, 0x127fffffffffff]` || ShadowGap  ||
100309124Sdim// || `[0x10000000000000, 0x11ffffffffffff]` || LowShadow  ||
101309124Sdim// || `[0x00000000000000, 0x0fffffffffffff]` || LowMem     ||
102309124Sdim//
103353358Sdim// Default Linux/SPARC64 (52-bit VMA) mapping:
104353358Sdim// || `[0x8000000000000, 0xfffffffffffff]` || HighMem    ||
105353358Sdim// || `[0x1080000000000, 0x207ffffffffff]` || HighShadow ||
106353358Sdim// || `[0x0090000000000, 0x107ffffffffff]` || ShadowGap  ||
107353358Sdim// || `[0x0080000000000, 0x008ffffffffff]` || LowShadow  ||
108353358Sdim// || `[0x0000000000000, 0x007ffffffffff]` || LowMem     ||
109353358Sdim//
110276789Sdim// Shadow mapping on FreeBSD/x86-64 with SHADOW_OFFSET == 0x400000000000:
111276789Sdim// || `[0x500000000000, 0x7fffffffffff]` || HighMem    ||
112276789Sdim// || `[0x4a0000000000, 0x4fffffffffff]` || HighShadow ||
113276789Sdim// || `[0x480000000000, 0x49ffffffffff]` || ShadowGap  ||
114276789Sdim// || `[0x400000000000, 0x47ffffffffff]` || LowShadow  ||
115276789Sdim// || `[0x000000000000, 0x3fffffffffff]` || LowMem     ||
116276789Sdim//
117276789Sdim// Shadow mapping on FreeBSD/i386 with SHADOW_OFFSET == 0x40000000:
118276789Sdim// || `[0x60000000, 0xffffffff]` || HighMem    ||
119276789Sdim// || `[0x4c000000, 0x5fffffff]` || HighShadow ||
120276789Sdim// || `[0x48000000, 0x4bffffff]` || ShadowGap  ||
121276789Sdim// || `[0x40000000, 0x47ffffff]` || LowShadow  ||
122276789Sdim// || `[0x00000000, 0x3fffffff]` || LowMem     ||
123280031Sdim//
124327952Sdim// Shadow mapping on NetBSD/x86-64 with SHADOW_OFFSET == 0x400000000000:
125327952Sdim// || `[0x4feffffffe01, 0x7f7ffffff000]` || HighMem    ||
126327952Sdim// || `[0x49fdffffffc0, 0x4feffffffe00]` || HighShadow ||
127327952Sdim// || `[0x480000000000, 0x49fdffffffbf]` || ShadowGap  ||
128327952Sdim// || `[0x400000000000, 0x47ffffffffff]` || LowShadow  ||
129327952Sdim// || `[0x000000000000, 0x3fffffffffff]` || LowMem     ||
130327952Sdim//
131341825Sdim// Shadow mapping on NetBSD/i386 with SHADOW_OFFSET == 0x40000000:
132341825Sdim// || `[0x60000000, 0xfffff000]` || HighMem    ||
133341825Sdim// || `[0x4c000000, 0x5fffffff]` || HighShadow ||
134341825Sdim// || `[0x48000000, 0x4bffffff]` || ShadowGap  ||
135341825Sdim// || `[0x40000000, 0x47ffffff]` || LowShadow  ||
136341825Sdim// || `[0x00000000, 0x3fffffff]` || LowMem     ||
137341825Sdim//
138280031Sdim// Default Windows/i386 mapping:
139280031Sdim// (the exact location of HighShadow/HighMem may vary depending
140280031Sdim//  on WoW64, /LARGEADDRESSAWARE, etc).
141280031Sdim// || `[0x50000000, 0xffffffff]` || HighMem    ||
142280031Sdim// || `[0x3a000000, 0x4fffffff]` || HighShadow ||
143280031Sdim// || `[0x36000000, 0x39ffffff]` || ShadowGap  ||
144280031Sdim// || `[0x30000000, 0x35ffffff]` || LowShadow  ||
145280031Sdim// || `[0x00000000, 0x2fffffff]` || LowMem     ||
146341825Sdim//
147341825Sdim// Shadow mapping on Myriad2 (for shadow scale 5):
148341825Sdim// || `[0x9ff80000, 0x9fffffff]` || ShadowGap  ||
149341825Sdim// || `[0x9f000000, 0x9ff7ffff]` || LowShadow  ||
150341825Sdim// || `[0x80000000, 0x9effffff]` || LowMem     ||
151341825Sdim// || `[0x00000000, 0x7fffffff]` || Ignored    ||
152229109Sed
153327952Sdim#if defined(ASAN_SHADOW_SCALE)
154327952Sdimstatic const u64 kDefaultShadowScale = ASAN_SHADOW_SCALE;
155327952Sdim#else
156341825Sdimstatic const u64 kDefaultShadowScale = SANITIZER_MYRIAD2 ? 5 : 3;
157327952Sdim#endif
158314564Sdimstatic const u64 kDefaultShadowSentinel = ~(uptr)0;
159276789Sdimstatic const u64 kDefaultShadowOffset32 = 1ULL << 29;  // 0x20000000
160274201Sdimstatic const u64 kDefaultShadowOffset64 = 1ULL << 44;
161327952Sdimstatic const u64 kDefaultShort64bitShadowOffset =
162327952Sdim    0x7FFFFFFF & (~0xFFFULL << kDefaultShadowScale);  // < 2G.
163276789Sdimstatic const u64 kAArch64_ShadowOffset64 = 1ULL << 36;
164276789Sdimstatic const u64 kMIPS32_ShadowOffset32 = 0x0aaa0000;
165280031Sdimstatic const u64 kMIPS64_ShadowOffset64 = 1ULL << 37;
166327952Sdimstatic const u64 kPPC64_ShadowOffset64 = 1ULL << 44;
167309124Sdimstatic const u64 kSystemZ_ShadowOffset64 = 1ULL << 52;
168353358Sdimstatic const u64 kSPARC64_ShadowOffset64 = 1ULL << 43;  // 0x80000000000
169276789Sdimstatic const u64 kFreeBSD_ShadowOffset32 = 1ULL << 30;  // 0x40000000
170276789Sdimstatic const u64 kFreeBSD_ShadowOffset64 = 1ULL << 46;  // 0x400000000000
171341825Sdimstatic const u64 kNetBSD_ShadowOffset32 = 1ULL << 30;  // 0x40000000
172327952Sdimstatic const u64 kNetBSD_ShadowOffset64 = 1ULL << 46;  // 0x400000000000
173280031Sdimstatic const u64 kWindowsShadowOffset32 = 3ULL << 28;  // 0x30000000
174274201Sdim
175341825Sdimstatic const u64 kMyriadMemoryOffset32 = 0x80000000ULL;
176341825Sdimstatic const u64 kMyriadMemorySize32 = 0x20000000ULL;
177341825Sdimstatic const u64 kMyriadMemoryEnd32 =
178341825Sdim    kMyriadMemoryOffset32 + kMyriadMemorySize32 - 1;
179341825Sdimstatic const u64 kMyriadShadowOffset32 =
180341825Sdim    (kMyriadMemoryOffset32 + kMyriadMemorySize32 -
181341825Sdim     (kMyriadMemorySize32 >> kDefaultShadowScale));
182341825Sdimstatic const u64 kMyriadCacheBitMask32 = 0x40000000ULL;
183341825Sdim
184276789Sdim#define SHADOW_SCALE kDefaultShadowScale
185296417Sdim
186327952Sdim#if SANITIZER_FUCHSIA
187327952Sdim#  define SHADOW_OFFSET (0)
188327952Sdim#elif SANITIZER_WORDSIZE == 32
189296417Sdim#  if SANITIZER_ANDROID
190327952Sdim#    define SHADOW_OFFSET __asan_shadow_memory_dynamic_address
191296417Sdim#  elif defined(__mips__)
192276789Sdim#    define SHADOW_OFFSET kMIPS32_ShadowOffset32
193276789Sdim#  elif SANITIZER_FREEBSD
194276789Sdim#    define SHADOW_OFFSET kFreeBSD_ShadowOffset32
195341825Sdim#  elif SANITIZER_NETBSD
196341825Sdim#    define SHADOW_OFFSET kNetBSD_ShadowOffset32
197288943Sdim#  elif SANITIZER_WINDOWS
198288943Sdim#    define SHADOW_OFFSET kWindowsShadowOffset32
199280031Sdim#  elif SANITIZER_IOS
200353358Sdim#    define SHADOW_OFFSET __asan_shadow_memory_dynamic_address
201341825Sdim#  elif SANITIZER_MYRIAD2
202341825Sdim#    define SHADOW_OFFSET kMyriadShadowOffset32
203276789Sdim#  else
204280031Sdim#    define SHADOW_OFFSET kDefaultShadowOffset32
205276789Sdim#  endif
206296417Sdim#else
207309124Sdim#  if SANITIZER_IOS
208353358Sdim#    define SHADOW_OFFSET __asan_shadow_memory_dynamic_address
209309124Sdim#  elif defined(__aarch64__)
210276789Sdim#    define SHADOW_OFFSET kAArch64_ShadowOffset64
211276789Sdim#  elif defined(__powerpc64__)
212276789Sdim#    define SHADOW_OFFSET kPPC64_ShadowOffset64
213309124Sdim#  elif defined(__s390x__)
214309124Sdim#    define SHADOW_OFFSET kSystemZ_ShadowOffset64
215276789Sdim#  elif SANITIZER_FREEBSD
216276789Sdim#    define SHADOW_OFFSET kFreeBSD_ShadowOffset64
217327952Sdim#  elif SANITIZER_NETBSD
218327952Sdim#    define SHADOW_OFFSET kNetBSD_ShadowOffset64
219276789Sdim#  elif SANITIZER_MAC
220276789Sdim#   define SHADOW_OFFSET kDefaultShadowOffset64
221276789Sdim#  elif defined(__mips64)
222276789Sdim#   define SHADOW_OFFSET kMIPS64_ShadowOffset64
223353358Sdim#elif defined(__sparc__)
224353358Sdim#define SHADOW_OFFSET kSPARC64_ShadowOffset64
225309124Sdim#  elif SANITIZER_WINDOWS64
226314564Sdim#   define SHADOW_OFFSET __asan_shadow_memory_dynamic_address
227238901Sandrew#  else
228276789Sdim#   define SHADOW_OFFSET kDefaultShort64bitShadowOffset
229238901Sandrew#  endif
230276789Sdim#endif
231229109Sed
232327952Sdim#if SANITIZER_ANDROID && defined(__arm__)
233327952Sdim# define ASAN_PREMAP_SHADOW 1
234327952Sdim#else
235327952Sdim# define ASAN_PREMAP_SHADOW 0
236327952Sdim#endif
237327952Sdim
238229109Sed#define SHADOW_GRANULARITY (1ULL << SHADOW_SCALE)
239341825Sdim
240341825Sdim#define DO_ASAN_MAPPING_PROFILE 0  // Set to 1 to profile the functions below.
241341825Sdim
242341825Sdim#if DO_ASAN_MAPPING_PROFILE
243341825Sdim# define PROFILE_ASAN_MAPPING() AsanMappingProfile[__LINE__]++;
244341825Sdim#else
245341825Sdim# define PROFILE_ASAN_MAPPING()
246341825Sdim#endif
247341825Sdim
248341825Sdim// If 1, all shadow boundaries are constants.
249341825Sdim// Don't set to 1 other than for testing.
250341825Sdim#define ASAN_FIXED_MAPPING 0
251341825Sdim
252341825Sdimnamespace __asan {
253341825Sdim
254341825Sdimextern uptr AsanMappingProfile[];
255341825Sdim
256341825Sdim#if ASAN_FIXED_MAPPING
257341825Sdim// Fixed mapping for 64-bit Linux. Mostly used for performance comparison
258341825Sdim// with non-fixed mapping. As of r175253 (Feb 2013) the performance
259341825Sdim// difference between fixed and non-fixed mapping is below the noise level.
260341825Sdimstatic uptr kHighMemEnd = 0x7fffffffffffULL;
261341825Sdimstatic uptr kMidMemBeg =    0x3000000000ULL;
262341825Sdimstatic uptr kMidMemEnd =    0x4fffffffffULL;
263341825Sdim#else
264341825Sdimextern uptr kHighMemEnd, kMidMemBeg, kMidMemEnd;  // Initialized in __asan_init.
265341825Sdim#endif
266341825Sdim
267341825Sdim}  // namespace __asan
268341825Sdim
269341825Sdim#if SANITIZER_MYRIAD2
270341825Sdim#include "asan_mapping_myriad.h"
271353358Sdim#elif defined(__sparc__) && SANITIZER_WORDSIZE == 64
272353358Sdim#include "asan_mapping_sparc64.h"
273341825Sdim#else
274251034Sed#define MEM_TO_SHADOW(mem) (((mem) >> SHADOW_SCALE) + (SHADOW_OFFSET))
275229109Sed
276229109Sed#define kLowMemBeg      0
277229109Sed#define kLowMemEnd      (SHADOW_OFFSET ? SHADOW_OFFSET - 1 : 0)
278229109Sed
279229109Sed#define kLowShadowBeg   SHADOW_OFFSET
280229109Sed#define kLowShadowEnd   MEM_TO_SHADOW(kLowMemEnd)
281229109Sed
282229109Sed#define kHighMemBeg     (MEM_TO_SHADOW(kHighMemEnd) + 1)
283229109Sed
284229109Sed#define kHighShadowBeg  MEM_TO_SHADOW(kHighMemBeg)
285229109Sed#define kHighShadowEnd  MEM_TO_SHADOW(kHighMemEnd)
286229109Sed
287251034Sed# define kMidShadowBeg MEM_TO_SHADOW(kMidMemBeg)
288251034Sed# define kMidShadowEnd MEM_TO_SHADOW(kMidMemEnd)
289251034Sed
290245614Sandrew// With the zero shadow base we can not actually map pages starting from 0.
291245614Sandrew// This constant is somewhat arbitrary.
292296417Sdim#define kZeroBaseShadowStart 0
293296417Sdim#define kZeroBaseMaxShadowStart (1 << 18)
294245614Sandrew
295245614Sandrew#define kShadowGapBeg   (kLowShadowEnd ? kLowShadowEnd + 1 \
296245614Sandrew                                       : kZeroBaseShadowStart)
297251034Sed#define kShadowGapEnd   ((kMidMemBeg ? kMidShadowBeg : kHighShadowBeg) - 1)
298229109Sed
299251034Sed#define kShadowGap2Beg (kMidMemBeg ? kMidShadowEnd + 1 : 0)
300251034Sed#define kShadowGap2End (kMidMemBeg ? kMidMemBeg - 1 : 0)
301229109Sed
302251034Sed#define kShadowGap3Beg (kMidMemBeg ? kMidMemEnd + 1 : 0)
303251034Sed#define kShadowGap3End (kMidMemBeg ? kHighShadowBeg - 1 : 0)
304251034Sed
305229109Sednamespace __asan {
306229109Sed
307238901Sandrewstatic inline bool AddrIsInLowMem(uptr a) {
308251034Sed  PROFILE_ASAN_MAPPING();
309341825Sdim  return a <= kLowMemEnd;
310229109Sed}
311229109Sed
312238901Sandrewstatic inline bool AddrIsInLowShadow(uptr a) {
313251034Sed  PROFILE_ASAN_MAPPING();
314229109Sed  return a >= kLowShadowBeg && a <= kLowShadowEnd;
315229109Sed}
316229109Sed
317341825Sdimstatic inline bool AddrIsInMidMem(uptr a) {
318341825Sdim  PROFILE_ASAN_MAPPING();
319341825Sdim  return kMidMemBeg && a >= kMidMemBeg && a <= kMidMemEnd;
320341825Sdim}
321341825Sdim
322341825Sdimstatic inline bool AddrIsInMidShadow(uptr a) {
323341825Sdim  PROFILE_ASAN_MAPPING();
324341825Sdim  return kMidMemBeg && a >= kMidShadowBeg && a <= kMidShadowEnd;
325341825Sdim}
326341825Sdim
327238901Sandrewstatic inline bool AddrIsInHighMem(uptr a) {
328251034Sed  PROFILE_ASAN_MAPPING();
329341825Sdim  return kHighMemBeg && a >= kHighMemBeg && a <= kHighMemEnd;
330229109Sed}
331229109Sed
332341825Sdimstatic inline bool AddrIsInHighShadow(uptr a) {
333251034Sed  PROFILE_ASAN_MAPPING();
334341825Sdim  return kHighMemBeg && a >= kHighShadowBeg && a <= kHighShadowEnd;
335251034Sed}
336251034Sed
337314564Sdimstatic inline bool AddrIsInShadowGap(uptr a) {
338314564Sdim  PROFILE_ASAN_MAPPING();
339314564Sdim  if (kMidMemBeg) {
340314564Sdim    if (a <= kShadowGapEnd)
341314564Sdim      return SHADOW_OFFSET == 0 || a >= kShadowGapBeg;
342314564Sdim    return (a >= kShadowGap2Beg && a <= kShadowGap2End) ||
343314564Sdim           (a >= kShadowGap3Beg && a <= kShadowGap3End);
344314564Sdim  }
345314564Sdim  // In zero-based shadow mode we treat addresses near zero as addresses
346314564Sdim  // in shadow gap as well.
347314564Sdim  if (SHADOW_OFFSET == 0)
348314564Sdim    return a <= kShadowGapEnd;
349314564Sdim  return a >= kShadowGapBeg && a <= kShadowGapEnd;
350314564Sdim}
351314564Sdim
352341825Sdim}  // namespace __asan
353341825Sdim
354341825Sdim#endif  // SANITIZER_MYRIAD2
355341825Sdim
356341825Sdimnamespace __asan {
357341825Sdim
358238901Sandrewstatic inline bool AddrIsInMem(uptr a) {
359251034Sed  PROFILE_ASAN_MAPPING();
360314564Sdim  return AddrIsInLowMem(a) || AddrIsInMidMem(a) || AddrIsInHighMem(a) ||
361314564Sdim      (flags()->protect_shadow_gap == 0 && AddrIsInShadowGap(a));
362229109Sed}
363229109Sed
364238901Sandrewstatic inline uptr MemToShadow(uptr p) {
365251034Sed  PROFILE_ASAN_MAPPING();
366229109Sed  CHECK(AddrIsInMem(p));
367229109Sed  return MEM_TO_SHADOW(p);
368229109Sed}
369229109Sed
370238901Sandrewstatic inline bool AddrIsInShadow(uptr a) {
371251034Sed  PROFILE_ASAN_MAPPING();
372251034Sed  return AddrIsInLowShadow(a) || AddrIsInMidShadow(a) || AddrIsInHighShadow(a);
373229109Sed}
374229109Sed
375238901Sandrewstatic inline bool AddrIsAlignedByGranularity(uptr a) {
376251034Sed  PROFILE_ASAN_MAPPING();
377229109Sed  return (a & (SHADOW_GRANULARITY - 1)) == 0;
378229109Sed}
379229109Sed
380238901Sandrewstatic inline bool AddressIsPoisoned(uptr a) {
381251034Sed  PROFILE_ASAN_MAPPING();
382341825Sdim  if (SANITIZER_MYRIAD2 && !AddrIsInMem(a) && !AddrIsInShadow(a))
383341825Sdim    return false;
384238901Sandrew  const uptr kAccessSize = 1;
385251034Sed  u8 *shadow_address = (u8*)MEM_TO_SHADOW(a);
386238901Sandrew  s8 shadow_value = *shadow_address;
387238901Sandrew  if (shadow_value) {
388238901Sandrew    u8 last_accessed_byte = (a & (SHADOW_GRANULARITY - 1))
389238901Sandrew                                 + kAccessSize - 1;
390238901Sandrew    return (last_accessed_byte >= shadow_value);
391238901Sandrew  }
392238901Sandrew  return false;
393238901Sandrew}
394238901Sandrew
395251034Sed// Must be after all calls to PROFILE_ASAN_MAPPING().
396251034Sedstatic const uptr kAsanMappingProfileSize = __LINE__;
397251034Sed
398229109Sed}  // namespace __asan
399229109Sed
400229109Sed#endif  // ASAN_MAPPING_H
401