1*7c3d14c8STreehugger Robot //===-- asan_mapping.h ------------------------------------------*- C++ -*-===//
2*7c3d14c8STreehugger Robot //
3*7c3d14c8STreehugger Robot // The LLVM Compiler Infrastructure
4*7c3d14c8STreehugger Robot //
5*7c3d14c8STreehugger Robot // This file is distributed under the University of Illinois Open Source
6*7c3d14c8STreehugger Robot // License. See LICENSE.TXT for details.
7*7c3d14c8STreehugger Robot //
8*7c3d14c8STreehugger Robot //===----------------------------------------------------------------------===//
9*7c3d14c8STreehugger Robot //
10*7c3d14c8STreehugger Robot // This file is a part of AddressSanitizer, an address sanity checker.
11*7c3d14c8STreehugger Robot //
12*7c3d14c8STreehugger Robot // Defines ASan memory mapping.
13*7c3d14c8STreehugger Robot //===----------------------------------------------------------------------===//
14*7c3d14c8STreehugger Robot #ifndef ASAN_MAPPING_H
15*7c3d14c8STreehugger Robot #define ASAN_MAPPING_H
16*7c3d14c8STreehugger Robot
17*7c3d14c8STreehugger Robot #include "asan_internal.h"
18*7c3d14c8STreehugger Robot
19*7c3d14c8STreehugger Robot // The full explanation of the memory mapping could be found here:
20*7c3d14c8STreehugger Robot // https://github.com/google/sanitizers/wiki/AddressSanitizerAlgorithm
21*7c3d14c8STreehugger Robot //
22*7c3d14c8STreehugger Robot // Typical shadow mapping on Linux/x86_64 with SHADOW_OFFSET == 0x00007fff8000:
23*7c3d14c8STreehugger Robot // || `[0x10007fff8000, 0x7fffffffffff]` || HighMem ||
24*7c3d14c8STreehugger Robot // || `[0x02008fff7000, 0x10007fff7fff]` || HighShadow ||
25*7c3d14c8STreehugger Robot // || `[0x00008fff7000, 0x02008fff6fff]` || ShadowGap ||
26*7c3d14c8STreehugger Robot // || `[0x00007fff8000, 0x00008fff6fff]` || LowShadow ||
27*7c3d14c8STreehugger Robot // || `[0x000000000000, 0x00007fff7fff]` || LowMem ||
28*7c3d14c8STreehugger Robot //
29*7c3d14c8STreehugger Robot // When SHADOW_OFFSET is zero (-pie):
30*7c3d14c8STreehugger Robot // || `[0x100000000000, 0x7fffffffffff]` || HighMem ||
31*7c3d14c8STreehugger Robot // || `[0x020000000000, 0x0fffffffffff]` || HighShadow ||
32*7c3d14c8STreehugger Robot // || `[0x000000040000, 0x01ffffffffff]` || ShadowGap ||
33*7c3d14c8STreehugger Robot //
34*7c3d14c8STreehugger Robot // Special case when something is already mapped between
35*7c3d14c8STreehugger Robot // 0x003000000000 and 0x005000000000 (e.g. when prelink is installed):
36*7c3d14c8STreehugger Robot // || `[0x10007fff8000, 0x7fffffffffff]` || HighMem ||
37*7c3d14c8STreehugger Robot // || `[0x02008fff7000, 0x10007fff7fff]` || HighShadow ||
38*7c3d14c8STreehugger Robot // || `[0x005000000000, 0x02008fff6fff]` || ShadowGap3 ||
39*7c3d14c8STreehugger Robot // || `[0x003000000000, 0x004fffffffff]` || MidMem ||
40*7c3d14c8STreehugger Robot // || `[0x000a7fff8000, 0x002fffffffff]` || ShadowGap2 ||
41*7c3d14c8STreehugger Robot // || `[0x00067fff8000, 0x000a7fff7fff]` || MidShadow ||
42*7c3d14c8STreehugger Robot // || `[0x00008fff7000, 0x00067fff7fff]` || ShadowGap ||
43*7c3d14c8STreehugger Robot // || `[0x00007fff8000, 0x00008fff6fff]` || LowShadow ||
44*7c3d14c8STreehugger Robot // || `[0x000000000000, 0x00007fff7fff]` || LowMem ||
45*7c3d14c8STreehugger Robot //
46*7c3d14c8STreehugger Robot // Default Linux/i386 mapping on x86_64 machine:
47*7c3d14c8STreehugger Robot // || `[0x40000000, 0xffffffff]` || HighMem ||
48*7c3d14c8STreehugger Robot // || `[0x28000000, 0x3fffffff]` || HighShadow ||
49*7c3d14c8STreehugger Robot // || `[0x24000000, 0x27ffffff]` || ShadowGap ||
50*7c3d14c8STreehugger Robot // || `[0x20000000, 0x23ffffff]` || LowShadow ||
51*7c3d14c8STreehugger Robot // || `[0x00000000, 0x1fffffff]` || LowMem ||
52*7c3d14c8STreehugger Robot //
53*7c3d14c8STreehugger Robot // Default Linux/i386 mapping on i386 machine
54*7c3d14c8STreehugger Robot // (addresses starting with 0xc0000000 are reserved
55*7c3d14c8STreehugger Robot // for kernel and thus not sanitized):
56*7c3d14c8STreehugger Robot // || `[0x38000000, 0xbfffffff]` || HighMem ||
57*7c3d14c8STreehugger Robot // || `[0x27000000, 0x37ffffff]` || HighShadow ||
58*7c3d14c8STreehugger Robot // || `[0x24000000, 0x26ffffff]` || ShadowGap ||
59*7c3d14c8STreehugger Robot // || `[0x20000000, 0x23ffffff]` || LowShadow ||
60*7c3d14c8STreehugger Robot // || `[0x00000000, 0x1fffffff]` || LowMem ||
61*7c3d14c8STreehugger Robot //
62*7c3d14c8STreehugger Robot // Default Linux/MIPS32 mapping:
63*7c3d14c8STreehugger Robot // || `[0x2aaa0000, 0xffffffff]` || HighMem ||
64*7c3d14c8STreehugger Robot // || `[0x0fff4000, 0x2aa9ffff]` || HighShadow ||
65*7c3d14c8STreehugger Robot // || `[0x0bff4000, 0x0fff3fff]` || ShadowGap ||
66*7c3d14c8STreehugger Robot // || `[0x0aaa0000, 0x0bff3fff]` || LowShadow ||
67*7c3d14c8STreehugger Robot // || `[0x00000000, 0x0aa9ffff]` || LowMem ||
68*7c3d14c8STreehugger Robot //
69*7c3d14c8STreehugger Robot // Default Linux/MIPS64 mapping:
70*7c3d14c8STreehugger Robot // || `[0x4000000000, 0xffffffffff]` || HighMem ||
71*7c3d14c8STreehugger Robot // || `[0x2800000000, 0x3fffffffff]` || HighShadow ||
72*7c3d14c8STreehugger Robot // || `[0x2400000000, 0x27ffffffff]` || ShadowGap ||
73*7c3d14c8STreehugger Robot // || `[0x2000000000, 0x23ffffffff]` || LowShadow ||
74*7c3d14c8STreehugger Robot // || `[0x0000000000, 0x1fffffffff]` || LowMem ||
75*7c3d14c8STreehugger Robot //
76*7c3d14c8STreehugger Robot // Default Linux/AArch64 (39-bit VMA) mapping:
77*7c3d14c8STreehugger Robot // || `[0x2000000000, 0x7fffffffff]` || highmem ||
78*7c3d14c8STreehugger Robot // || `[0x1400000000, 0x1fffffffff]` || highshadow ||
79*7c3d14c8STreehugger Robot // || `[0x1200000000, 0x13ffffffff]` || shadowgap ||
80*7c3d14c8STreehugger Robot // || `[0x1000000000, 0x11ffffffff]` || lowshadow ||
81*7c3d14c8STreehugger Robot // || `[0x0000000000, 0x0fffffffff]` || lowmem ||
82*7c3d14c8STreehugger Robot //
83*7c3d14c8STreehugger Robot // Default Linux/AArch64 (42-bit VMA) mapping:
84*7c3d14c8STreehugger Robot // || `[0x10000000000, 0x3ffffffffff]` || highmem ||
85*7c3d14c8STreehugger Robot // || `[0x0a000000000, 0x0ffffffffff]` || highshadow ||
86*7c3d14c8STreehugger Robot // || `[0x09000000000, 0x09fffffffff]` || shadowgap ||
87*7c3d14c8STreehugger Robot // || `[0x08000000000, 0x08fffffffff]` || lowshadow ||
88*7c3d14c8STreehugger Robot // || `[0x00000000000, 0x07fffffffff]` || lowmem ||
89*7c3d14c8STreehugger Robot //
90*7c3d14c8STreehugger Robot // Default Linux/S390 mapping:
91*7c3d14c8STreehugger Robot // || `[0x30000000, 0x7fffffff]` || HighMem ||
92*7c3d14c8STreehugger Robot // || `[0x26000000, 0x2fffffff]` || HighShadow ||
93*7c3d14c8STreehugger Robot // || `[0x24000000, 0x25ffffff]` || ShadowGap ||
94*7c3d14c8STreehugger Robot // || `[0x20000000, 0x23ffffff]` || LowShadow ||
95*7c3d14c8STreehugger Robot // || `[0x00000000, 0x1fffffff]` || LowMem ||
96*7c3d14c8STreehugger Robot //
97*7c3d14c8STreehugger Robot // Default Linux/SystemZ mapping:
98*7c3d14c8STreehugger Robot // || `[0x14000000000000, 0x1fffffffffffff]` || HighMem ||
99*7c3d14c8STreehugger Robot // || `[0x12800000000000, 0x13ffffffffffff]` || HighShadow ||
100*7c3d14c8STreehugger Robot // || `[0x12000000000000, 0x127fffffffffff]` || ShadowGap ||
101*7c3d14c8STreehugger Robot // || `[0x10000000000000, 0x11ffffffffffff]` || LowShadow ||
102*7c3d14c8STreehugger Robot // || `[0x00000000000000, 0x0fffffffffffff]` || LowMem ||
103*7c3d14c8STreehugger Robot //
104*7c3d14c8STreehugger Robot // Shadow mapping on FreeBSD/x86-64 with SHADOW_OFFSET == 0x400000000000:
105*7c3d14c8STreehugger Robot // || `[0x500000000000, 0x7fffffffffff]` || HighMem ||
106*7c3d14c8STreehugger Robot // || `[0x4a0000000000, 0x4fffffffffff]` || HighShadow ||
107*7c3d14c8STreehugger Robot // || `[0x480000000000, 0x49ffffffffff]` || ShadowGap ||
108*7c3d14c8STreehugger Robot // || `[0x400000000000, 0x47ffffffffff]` || LowShadow ||
109*7c3d14c8STreehugger Robot // || `[0x000000000000, 0x3fffffffffff]` || LowMem ||
110*7c3d14c8STreehugger Robot //
111*7c3d14c8STreehugger Robot // Shadow mapping on FreeBSD/i386 with SHADOW_OFFSET == 0x40000000:
112*7c3d14c8STreehugger Robot // || `[0x60000000, 0xffffffff]` || HighMem ||
113*7c3d14c8STreehugger Robot // || `[0x4c000000, 0x5fffffff]` || HighShadow ||
114*7c3d14c8STreehugger Robot // || `[0x48000000, 0x4bffffff]` || ShadowGap ||
115*7c3d14c8STreehugger Robot // || `[0x40000000, 0x47ffffff]` || LowShadow ||
116*7c3d14c8STreehugger Robot // || `[0x00000000, 0x3fffffff]` || LowMem ||
117*7c3d14c8STreehugger Robot //
118*7c3d14c8STreehugger Robot // Default Windows/i386 mapping:
119*7c3d14c8STreehugger Robot // (the exact location of HighShadow/HighMem may vary depending
120*7c3d14c8STreehugger Robot // on WoW64, /LARGEADDRESSAWARE, etc).
121*7c3d14c8STreehugger Robot // || `[0x50000000, 0xffffffff]` || HighMem ||
122*7c3d14c8STreehugger Robot // || `[0x3a000000, 0x4fffffff]` || HighShadow ||
123*7c3d14c8STreehugger Robot // || `[0x36000000, 0x39ffffff]` || ShadowGap ||
124*7c3d14c8STreehugger Robot // || `[0x30000000, 0x35ffffff]` || LowShadow ||
125*7c3d14c8STreehugger Robot // || `[0x00000000, 0x2fffffff]` || LowMem ||
126*7c3d14c8STreehugger Robot
127*7c3d14c8STreehugger Robot static const u64 kDefaultShadowScale = 3;
128*7c3d14c8STreehugger Robot static const u64 kDefaultShadowOffset32 = 1ULL << 29; // 0x20000000
129*7c3d14c8STreehugger Robot static const u64 kDefaultShadowOffset64 = 1ULL << 44;
130*7c3d14c8STreehugger Robot static const u64 kDefaultShort64bitShadowOffset = 0x7FFF8000; // < 2G.
131*7c3d14c8STreehugger Robot static const u64 kIosShadowOffset32 = 1ULL << 30; // 0x40000000
132*7c3d14c8STreehugger Robot static const u64 kIosShadowOffset64 = 0x120200000;
133*7c3d14c8STreehugger Robot static const u64 kIosSimShadowOffset32 = 1ULL << 30;
134*7c3d14c8STreehugger Robot static const u64 kIosSimShadowOffset64 = kDefaultShadowOffset64;
135*7c3d14c8STreehugger Robot static const u64 kAArch64_ShadowOffset64 = 1ULL << 36;
136*7c3d14c8STreehugger Robot static const u64 kMIPS32_ShadowOffset32 = 0x0aaa0000;
137*7c3d14c8STreehugger Robot static const u64 kMIPS64_ShadowOffset64 = 1ULL << 37;
138*7c3d14c8STreehugger Robot static const u64 kPPC64_ShadowOffset64 = 1ULL << 41;
139*7c3d14c8STreehugger Robot static const u64 kSystemZ_ShadowOffset64 = 1ULL << 52;
140*7c3d14c8STreehugger Robot static const u64 kFreeBSD_ShadowOffset32 = 1ULL << 30; // 0x40000000
141*7c3d14c8STreehugger Robot static const u64 kFreeBSD_ShadowOffset64 = 1ULL << 46; // 0x400000000000
142*7c3d14c8STreehugger Robot static const u64 kWindowsShadowOffset32 = 3ULL << 28; // 0x30000000
143*7c3d14c8STreehugger Robot static const u64 kWindowsShadowOffset64 = 1ULL << 45; // 32TB
144*7c3d14c8STreehugger Robot
145*7c3d14c8STreehugger Robot #define SHADOW_SCALE kDefaultShadowScale
146*7c3d14c8STreehugger Robot
147*7c3d14c8STreehugger Robot
148*7c3d14c8STreehugger Robot #if SANITIZER_WORDSIZE == 32
149*7c3d14c8STreehugger Robot # if SANITIZER_ANDROID
150*7c3d14c8STreehugger Robot # define SHADOW_OFFSET (0)
151*7c3d14c8STreehugger Robot # elif defined(__mips__)
152*7c3d14c8STreehugger Robot # define SHADOW_OFFSET kMIPS32_ShadowOffset32
153*7c3d14c8STreehugger Robot # elif SANITIZER_FREEBSD
154*7c3d14c8STreehugger Robot # define SHADOW_OFFSET kFreeBSD_ShadowOffset32
155*7c3d14c8STreehugger Robot # elif SANITIZER_WINDOWS
156*7c3d14c8STreehugger Robot # define SHADOW_OFFSET kWindowsShadowOffset32
157*7c3d14c8STreehugger Robot # elif SANITIZER_IOS
158*7c3d14c8STreehugger Robot # if SANITIZER_IOSSIM
159*7c3d14c8STreehugger Robot # define SHADOW_OFFSET kIosSimShadowOffset32
160*7c3d14c8STreehugger Robot # else
161*7c3d14c8STreehugger Robot # define SHADOW_OFFSET kIosShadowOffset32
162*7c3d14c8STreehugger Robot # endif
163*7c3d14c8STreehugger Robot # else
164*7c3d14c8STreehugger Robot # define SHADOW_OFFSET kDefaultShadowOffset32
165*7c3d14c8STreehugger Robot # endif
166*7c3d14c8STreehugger Robot #else
167*7c3d14c8STreehugger Robot # if SANITIZER_IOS
168*7c3d14c8STreehugger Robot # if SANITIZER_IOSSIM
169*7c3d14c8STreehugger Robot # define SHADOW_OFFSET kIosSimShadowOffset64
170*7c3d14c8STreehugger Robot # else
171*7c3d14c8STreehugger Robot # define SHADOW_OFFSET kIosShadowOffset64
172*7c3d14c8STreehugger Robot # endif
173*7c3d14c8STreehugger Robot # elif defined(__aarch64__)
174*7c3d14c8STreehugger Robot # define SHADOW_OFFSET kAArch64_ShadowOffset64
175*7c3d14c8STreehugger Robot # elif defined(__powerpc64__)
176*7c3d14c8STreehugger Robot # define SHADOW_OFFSET kPPC64_ShadowOffset64
177*7c3d14c8STreehugger Robot # elif defined(__s390x__)
178*7c3d14c8STreehugger Robot # define SHADOW_OFFSET kSystemZ_ShadowOffset64
179*7c3d14c8STreehugger Robot # elif SANITIZER_FREEBSD
180*7c3d14c8STreehugger Robot # define SHADOW_OFFSET kFreeBSD_ShadowOffset64
181*7c3d14c8STreehugger Robot # elif SANITIZER_MAC
182*7c3d14c8STreehugger Robot # define SHADOW_OFFSET kDefaultShadowOffset64
183*7c3d14c8STreehugger Robot # elif defined(__mips64)
184*7c3d14c8STreehugger Robot # define SHADOW_OFFSET kMIPS64_ShadowOffset64
185*7c3d14c8STreehugger Robot # elif SANITIZER_WINDOWS64
186*7c3d14c8STreehugger Robot # define SHADOW_OFFSET kWindowsShadowOffset64
187*7c3d14c8STreehugger Robot # else
188*7c3d14c8STreehugger Robot # define SHADOW_OFFSET kDefaultShort64bitShadowOffset
189*7c3d14c8STreehugger Robot # endif
190*7c3d14c8STreehugger Robot #endif
191*7c3d14c8STreehugger Robot
192*7c3d14c8STreehugger Robot #define SHADOW_GRANULARITY (1ULL << SHADOW_SCALE)
193*7c3d14c8STreehugger Robot #define MEM_TO_SHADOW(mem) (((mem) >> SHADOW_SCALE) + (SHADOW_OFFSET))
194*7c3d14c8STreehugger Robot #define SHADOW_TO_MEM(shadow) (((shadow) - SHADOW_OFFSET) << SHADOW_SCALE)
195*7c3d14c8STreehugger Robot
196*7c3d14c8STreehugger Robot #define kLowMemBeg 0
197*7c3d14c8STreehugger Robot #define kLowMemEnd (SHADOW_OFFSET ? SHADOW_OFFSET - 1 : 0)
198*7c3d14c8STreehugger Robot
199*7c3d14c8STreehugger Robot #define kLowShadowBeg SHADOW_OFFSET
200*7c3d14c8STreehugger Robot #define kLowShadowEnd MEM_TO_SHADOW(kLowMemEnd)
201*7c3d14c8STreehugger Robot
202*7c3d14c8STreehugger Robot #define kHighMemBeg (MEM_TO_SHADOW(kHighMemEnd) + 1)
203*7c3d14c8STreehugger Robot
204*7c3d14c8STreehugger Robot #define kHighShadowBeg MEM_TO_SHADOW(kHighMemBeg)
205*7c3d14c8STreehugger Robot #define kHighShadowEnd MEM_TO_SHADOW(kHighMemEnd)
206*7c3d14c8STreehugger Robot
207*7c3d14c8STreehugger Robot # define kMidShadowBeg MEM_TO_SHADOW(kMidMemBeg)
208*7c3d14c8STreehugger Robot # define kMidShadowEnd MEM_TO_SHADOW(kMidMemEnd)
209*7c3d14c8STreehugger Robot
210*7c3d14c8STreehugger Robot // With the zero shadow base we can not actually map pages starting from 0.
211*7c3d14c8STreehugger Robot // This constant is somewhat arbitrary.
212*7c3d14c8STreehugger Robot #define kZeroBaseShadowStart 0
213*7c3d14c8STreehugger Robot #define kZeroBaseMaxShadowStart (1 << 18)
214*7c3d14c8STreehugger Robot
215*7c3d14c8STreehugger Robot #define kShadowGapBeg (kLowShadowEnd ? kLowShadowEnd + 1 \
216*7c3d14c8STreehugger Robot : kZeroBaseShadowStart)
217*7c3d14c8STreehugger Robot #define kShadowGapEnd ((kMidMemBeg ? kMidShadowBeg : kHighShadowBeg) - 1)
218*7c3d14c8STreehugger Robot
219*7c3d14c8STreehugger Robot #define kShadowGap2Beg (kMidMemBeg ? kMidShadowEnd + 1 : 0)
220*7c3d14c8STreehugger Robot #define kShadowGap2End (kMidMemBeg ? kMidMemBeg - 1 : 0)
221*7c3d14c8STreehugger Robot
222*7c3d14c8STreehugger Robot #define kShadowGap3Beg (kMidMemBeg ? kMidMemEnd + 1 : 0)
223*7c3d14c8STreehugger Robot #define kShadowGap3End (kMidMemBeg ? kHighShadowBeg - 1 : 0)
224*7c3d14c8STreehugger Robot
225*7c3d14c8STreehugger Robot #define DO_ASAN_MAPPING_PROFILE 0 // Set to 1 to profile the functions below.
226*7c3d14c8STreehugger Robot
227*7c3d14c8STreehugger Robot #if DO_ASAN_MAPPING_PROFILE
228*7c3d14c8STreehugger Robot # define PROFILE_ASAN_MAPPING() AsanMappingProfile[__LINE__]++;
229*7c3d14c8STreehugger Robot #else
230*7c3d14c8STreehugger Robot # define PROFILE_ASAN_MAPPING()
231*7c3d14c8STreehugger Robot #endif
232*7c3d14c8STreehugger Robot
233*7c3d14c8STreehugger Robot // If 1, all shadow boundaries are constants.
234*7c3d14c8STreehugger Robot // Don't set to 1 other than for testing.
235*7c3d14c8STreehugger Robot #define ASAN_FIXED_MAPPING 0
236*7c3d14c8STreehugger Robot
237*7c3d14c8STreehugger Robot namespace __asan {
238*7c3d14c8STreehugger Robot
239*7c3d14c8STreehugger Robot extern uptr AsanMappingProfile[];
240*7c3d14c8STreehugger Robot
241*7c3d14c8STreehugger Robot #if ASAN_FIXED_MAPPING
242*7c3d14c8STreehugger Robot // Fixed mapping for 64-bit Linux. Mostly used for performance comparison
243*7c3d14c8STreehugger Robot // with non-fixed mapping. As of r175253 (Feb 2013) the performance
244*7c3d14c8STreehugger Robot // difference between fixed and non-fixed mapping is below the noise level.
245*7c3d14c8STreehugger Robot static uptr kHighMemEnd = 0x7fffffffffffULL;
246*7c3d14c8STreehugger Robot static uptr kMidMemBeg = 0x3000000000ULL;
247*7c3d14c8STreehugger Robot static uptr kMidMemEnd = 0x4fffffffffULL;
248*7c3d14c8STreehugger Robot #else
249*7c3d14c8STreehugger Robot extern uptr kHighMemEnd, kMidMemBeg, kMidMemEnd; // Initialized in __asan_init.
250*7c3d14c8STreehugger Robot #endif
251*7c3d14c8STreehugger Robot
AddrIsInLowMem(uptr a)252*7c3d14c8STreehugger Robot static inline bool AddrIsInLowMem(uptr a) {
253*7c3d14c8STreehugger Robot PROFILE_ASAN_MAPPING();
254*7c3d14c8STreehugger Robot return a < kLowMemEnd;
255*7c3d14c8STreehugger Robot }
256*7c3d14c8STreehugger Robot
AddrIsInLowShadow(uptr a)257*7c3d14c8STreehugger Robot static inline bool AddrIsInLowShadow(uptr a) {
258*7c3d14c8STreehugger Robot PROFILE_ASAN_MAPPING();
259*7c3d14c8STreehugger Robot return a >= kLowShadowBeg && a <= kLowShadowEnd;
260*7c3d14c8STreehugger Robot }
261*7c3d14c8STreehugger Robot
AddrIsInHighMem(uptr a)262*7c3d14c8STreehugger Robot static inline bool AddrIsInHighMem(uptr a) {
263*7c3d14c8STreehugger Robot PROFILE_ASAN_MAPPING();
264*7c3d14c8STreehugger Robot return a >= kHighMemBeg && a <= kHighMemEnd;
265*7c3d14c8STreehugger Robot }
266*7c3d14c8STreehugger Robot
AddrIsInMidMem(uptr a)267*7c3d14c8STreehugger Robot static inline bool AddrIsInMidMem(uptr a) {
268*7c3d14c8STreehugger Robot PROFILE_ASAN_MAPPING();
269*7c3d14c8STreehugger Robot return kMidMemBeg && a >= kMidMemBeg && a <= kMidMemEnd;
270*7c3d14c8STreehugger Robot }
271*7c3d14c8STreehugger Robot
AddrIsInMem(uptr a)272*7c3d14c8STreehugger Robot static inline bool AddrIsInMem(uptr a) {
273*7c3d14c8STreehugger Robot PROFILE_ASAN_MAPPING();
274*7c3d14c8STreehugger Robot return AddrIsInLowMem(a) || AddrIsInMidMem(a) || AddrIsInHighMem(a);
275*7c3d14c8STreehugger Robot }
276*7c3d14c8STreehugger Robot
MemToShadow(uptr p)277*7c3d14c8STreehugger Robot static inline uptr MemToShadow(uptr p) {
278*7c3d14c8STreehugger Robot PROFILE_ASAN_MAPPING();
279*7c3d14c8STreehugger Robot CHECK(AddrIsInMem(p));
280*7c3d14c8STreehugger Robot return MEM_TO_SHADOW(p);
281*7c3d14c8STreehugger Robot }
282*7c3d14c8STreehugger Robot
AddrIsInHighShadow(uptr a)283*7c3d14c8STreehugger Robot static inline bool AddrIsInHighShadow(uptr a) {
284*7c3d14c8STreehugger Robot PROFILE_ASAN_MAPPING();
285*7c3d14c8STreehugger Robot return a >= kHighShadowBeg && a <= kHighMemEnd;
286*7c3d14c8STreehugger Robot }
287*7c3d14c8STreehugger Robot
AddrIsInMidShadow(uptr a)288*7c3d14c8STreehugger Robot static inline bool AddrIsInMidShadow(uptr a) {
289*7c3d14c8STreehugger Robot PROFILE_ASAN_MAPPING();
290*7c3d14c8STreehugger Robot return kMidMemBeg && a >= kMidShadowBeg && a <= kMidMemEnd;
291*7c3d14c8STreehugger Robot }
292*7c3d14c8STreehugger Robot
AddrIsInShadow(uptr a)293*7c3d14c8STreehugger Robot static inline bool AddrIsInShadow(uptr a) {
294*7c3d14c8STreehugger Robot PROFILE_ASAN_MAPPING();
295*7c3d14c8STreehugger Robot return AddrIsInLowShadow(a) || AddrIsInMidShadow(a) || AddrIsInHighShadow(a);
296*7c3d14c8STreehugger Robot }
297*7c3d14c8STreehugger Robot
AddrIsInShadowGap(uptr a)298*7c3d14c8STreehugger Robot static inline bool AddrIsInShadowGap(uptr a) {
299*7c3d14c8STreehugger Robot PROFILE_ASAN_MAPPING();
300*7c3d14c8STreehugger Robot if (kMidMemBeg) {
301*7c3d14c8STreehugger Robot if (a <= kShadowGapEnd)
302*7c3d14c8STreehugger Robot return SHADOW_OFFSET == 0 || a >= kShadowGapBeg;
303*7c3d14c8STreehugger Robot return (a >= kShadowGap2Beg && a <= kShadowGap2End) ||
304*7c3d14c8STreehugger Robot (a >= kShadowGap3Beg && a <= kShadowGap3End);
305*7c3d14c8STreehugger Robot }
306*7c3d14c8STreehugger Robot // In zero-based shadow mode we treat addresses near zero as addresses
307*7c3d14c8STreehugger Robot // in shadow gap as well.
308*7c3d14c8STreehugger Robot if (SHADOW_OFFSET == 0)
309*7c3d14c8STreehugger Robot return a <= kShadowGapEnd;
310*7c3d14c8STreehugger Robot return a >= kShadowGapBeg && a <= kShadowGapEnd;
311*7c3d14c8STreehugger Robot }
312*7c3d14c8STreehugger Robot
AddrIsAlignedByGranularity(uptr a)313*7c3d14c8STreehugger Robot static inline bool AddrIsAlignedByGranularity(uptr a) {
314*7c3d14c8STreehugger Robot PROFILE_ASAN_MAPPING();
315*7c3d14c8STreehugger Robot return (a & (SHADOW_GRANULARITY - 1)) == 0;
316*7c3d14c8STreehugger Robot }
317*7c3d14c8STreehugger Robot
AddressIsPoisoned(uptr a)318*7c3d14c8STreehugger Robot static inline bool AddressIsPoisoned(uptr a) {
319*7c3d14c8STreehugger Robot PROFILE_ASAN_MAPPING();
320*7c3d14c8STreehugger Robot const uptr kAccessSize = 1;
321*7c3d14c8STreehugger Robot u8 *shadow_address = (u8*)MEM_TO_SHADOW(a);
322*7c3d14c8STreehugger Robot s8 shadow_value = *shadow_address;
323*7c3d14c8STreehugger Robot if (shadow_value) {
324*7c3d14c8STreehugger Robot u8 last_accessed_byte = (a & (SHADOW_GRANULARITY - 1))
325*7c3d14c8STreehugger Robot + kAccessSize - 1;
326*7c3d14c8STreehugger Robot return (last_accessed_byte >= shadow_value);
327*7c3d14c8STreehugger Robot }
328*7c3d14c8STreehugger Robot return false;
329*7c3d14c8STreehugger Robot }
330*7c3d14c8STreehugger Robot
331*7c3d14c8STreehugger Robot // Must be after all calls to PROFILE_ASAN_MAPPING().
332*7c3d14c8STreehugger Robot static const uptr kAsanMappingProfileSize = __LINE__;
333*7c3d14c8STreehugger Robot
334*7c3d14c8STreehugger Robot } // namespace __asan
335*7c3d14c8STreehugger Robot
336*7c3d14c8STreehugger Robot #endif // ASAN_MAPPING_H
337