1 //===-- tsan_platform.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 ThreadSanitizer (TSan), a race detector.
10 //
11 // Platform-specific code.
12 //===----------------------------------------------------------------------===//
13
14 #ifndef TSAN_PLATFORM_H
15 #define TSAN_PLATFORM_H
16
17 #if !defined(__LP64__) && !defined(_WIN64)
18 # error "Only 64-bit is supported"
19 #endif
20
21 #include "sanitizer_common/sanitizer_common.h"
22 #include "tsan_defs.h"
23
24 namespace __tsan {
25
26 enum {
27 // App memory is not mapped onto shadow memory range.
28 kBrokenMapping = 1 << 0,
29 // Mapping app memory and back does not produce the same address,
30 // this can lead to wrong addresses in reports and potentially
31 // other bad consequences.
32 kBrokenReverseMapping = 1 << 1,
33 // Mapping is non-linear for linear user range.
34 // This is bad and can lead to unpredictable memory corruptions, etc
35 // because range access functions assume linearity.
36 kBrokenLinearity = 1 << 2,
37 // Meta for an app region overlaps with the meta of another app region.
38 // This is determined by recomputing the individual meta regions for
39 // each app region.
40 //
41 // N.B. There is no "kBrokenReverseMetaMapping" constant because there
42 // is no MetaToMem function. However, note that (!kBrokenLinearity
43 // && !kBrokenAliasedMetas) implies that MemToMeta is invertible.
44 kBrokenAliasedMetas = 1 << 3,
45 };
46
47 /*
48 C/C++ on linux/x86_64 and freebsd/x86_64
49 0000 0000 1000 - 0200 0000 0000: main binary and/or MAP_32BIT mappings (2TB)
50 0200 0000 0000 - 1000 0000 0000: -
51 1000 0000 0000 - 3000 0000 0000: shadow (32TB)
52 3000 0000 0000 - 3800 0000 0000: metainfo (memory blocks and sync objects; 8TB)
53 3800 0000 0000 - 5500 0000 0000: -
54 5500 0000 0000 - 5a00 0000 0000: pie binaries without ASLR or on 4.1+ kernels
55 5a00 0000 0000 - 7200 0000 0000: -
56 7200 0000 0000 - 7300 0000 0000: heap (1TB)
57 7300 0000 0000 - 7a00 0000 0000: -
58 7a00 0000 0000 - 8000 0000 0000: modules and main thread stack (6TB)
59
60 C/C++ on netbsd/amd64 can reuse the same mapping:
61 * The address space starts from 0x1000 (option with 0x0) and ends with
62 0x7f7ffffff000.
63 * LoAppMem-kHeapMemEnd can be reused as it is.
64 * No VDSO support.
65 * No MidAppMem region.
66 * No additional HeapMem region.
67 * HiAppMem contains the stack, loader, shared libraries and heap.
68 * Stack on NetBSD/amd64 has prereserved 128MB.
69 * Heap grows downwards (top-down).
70 * ASLR must be disabled per-process or globally.
71 */
72 struct Mapping48AddressSpace {
73 static const uptr kMetaShadowBeg = 0x300000000000ull;
74 static const uptr kMetaShadowEnd = 0x380000000000ull;
75 static const uptr kShadowBeg = 0x100000000000ull;
76 static const uptr kShadowEnd = 0x300000000000ull;
77 static const uptr kHeapMemBeg = 0x720000000000ull;
78 static const uptr kHeapMemEnd = 0x730000000000ull;
79 static const uptr kLoAppMemBeg = 0x000000001000ull;
80 static const uptr kLoAppMemEnd = 0x020000000000ull;
81 static const uptr kMidAppMemBeg = 0x550000000000ull;
82 static const uptr kMidAppMemEnd = 0x5a0000000000ull;
83 static const uptr kHiAppMemBeg = 0x7a0000000000ull;
84 static const uptr kHiAppMemEnd = 0x800000000000ull;
85 static const uptr kShadowMsk = 0x700000000000ull;
86 static const uptr kShadowXor = 0x000000000000ull;
87 static const uptr kShadowAdd = 0x100000000000ull;
88 static const uptr kVdsoBeg = 0xf000000000000000ull;
89 };
90
91 /*
92 C/C++ on linux/mips64 (40-bit VMA)
93 0000 0000 00 - 0100 0000 00: - (4 GB)
94 0100 0000 00 - 0200 0000 00: main binary (4 GB)
95 0200 0000 00 - 1200 0000 00: - (64 GB)
96 1200 0000 00 - 2200 0000 00: shadow (64 GB)
97 2200 0000 00 - 4000 0000 00: - (120 GB)
98 4000 0000 00 - 5000 0000 00: metainfo (memory blocks and sync objects) (64 GB)
99 5000 0000 00 - aa00 0000 00: - (360 GB)
100 aa00 0000 00 - ab00 0000 00: main binary (PIE) (4 GB)
101 ab00 0000 00 - fe00 0000 00: - (332 GB)
102 fe00 0000 00 - ff00 0000 00: heap (4 GB)
103 ff00 0000 00 - ff80 0000 00: - (2 GB)
104 ff80 0000 00 - ffff ffff ff: modules and main thread stack (<2 GB)
105 */
106 struct MappingMips64_40 {
107 static const uptr kMetaShadowBeg = 0x4000000000ull;
108 static const uptr kMetaShadowEnd = 0x5000000000ull;
109 static const uptr kShadowBeg = 0x1200000000ull;
110 static const uptr kShadowEnd = 0x2200000000ull;
111 static const uptr kHeapMemBeg = 0xfe00000000ull;
112 static const uptr kHeapMemEnd = 0xff00000000ull;
113 static const uptr kLoAppMemBeg = 0x0100000000ull;
114 static const uptr kLoAppMemEnd = 0x0200000000ull;
115 static const uptr kMidAppMemBeg = 0xaa00000000ull;
116 static const uptr kMidAppMemEnd = 0xab00000000ull;
117 static const uptr kHiAppMemBeg = 0xff80000000ull;
118 static const uptr kHiAppMemEnd = 0xffffffffffull;
119 static const uptr kShadowMsk = 0xf800000000ull;
120 static const uptr kShadowXor = 0x0800000000ull;
121 static const uptr kShadowAdd = 0x0000000000ull;
122 static const uptr kVdsoBeg = 0xfffff00000ull;
123 };
124
125 /*
126 C/C++ on Darwin/iOS/ARM64 (36-bit VMA, 64 GB VM)
127 0000 0000 00 - 0100 0000 00: - (4 GB)
128 0100 0000 00 - 0200 0000 00: main binary, modules, thread stacks (4 GB)
129 0200 0000 00 - 0300 0000 00: heap (4 GB)
130 0300 0000 00 - 0400 0000 00: - (4 GB)
131 0400 0000 00 - 0800 0000 00: shadow memory (16 GB)
132 0800 0000 00 - 0d00 0000 00: - (20 GB)
133 0d00 0000 00 - 0e00 0000 00: metainfo (4 GB)
134 0e00 0000 00 - 1000 0000 00: -
135 */
136 struct MappingAppleAarch64 {
137 static const uptr kLoAppMemBeg = 0x0100000000ull;
138 static const uptr kLoAppMemEnd = 0x0200000000ull;
139 static const uptr kHeapMemBeg = 0x0200000000ull;
140 static const uptr kHeapMemEnd = 0x0300000000ull;
141 static const uptr kShadowBeg = 0x0400000000ull;
142 static const uptr kShadowEnd = 0x0800000000ull;
143 static const uptr kMetaShadowBeg = 0x0d00000000ull;
144 static const uptr kMetaShadowEnd = 0x0e00000000ull;
145 static const uptr kHiAppMemBeg = 0x0fc0000000ull;
146 static const uptr kHiAppMemEnd = 0x0fc0000000ull;
147 static const uptr kShadowMsk = 0x0ull;
148 static const uptr kShadowXor = 0x0ull;
149 static const uptr kShadowAdd = 0x0200000000ull;
150 static const uptr kVdsoBeg = 0x7000000000000000ull;
151 static const uptr kMidAppMemBeg = 0;
152 static const uptr kMidAppMemEnd = 0;
153 };
154
155 /*
156 C/C++ on linux/aarch64 (39-bit VMA)
157 0000 0010 00 - 0500 0000 00: main binary (20 GB)
158 0100 0000 00 - 2000 0000 00: -
159 2000 0000 00 - 4000 0000 00: shadow memory (128 GB)
160 4000 0000 00 - 4800 0000 00: metainfo (32 GB)
161 4800 0000 00 - 5500 0000 00: -
162 5500 0000 00 - 5a00 0000 00: main binary (PIE) (20 GB)
163 5600 0000 00 - 7c00 0000 00: -
164 7a00 0000 00 - 7d00 0000 00: heap (12 GB)
165 7d00 0000 00 - 7fff ffff ff: modules and main thread stack (12 GB)
166 */
167 struct MappingAarch64_39 {
168 static const uptr kLoAppMemBeg = 0x0000001000ull;
169 static const uptr kLoAppMemEnd = 0x0500000000ull;
170 static const uptr kShadowBeg = 0x2000000000ull;
171 static const uptr kShadowEnd = 0x4000000000ull;
172 static const uptr kMetaShadowBeg = 0x4000000000ull;
173 static const uptr kMetaShadowEnd = 0x4800000000ull;
174 static const uptr kMidAppMemBeg = 0x5500000000ull;
175 static const uptr kMidAppMemEnd = 0x5a00000000ull;
176 static const uptr kHeapMemBeg = 0x7a00000000ull;
177 static const uptr kHeapMemEnd = 0x7d00000000ull;
178 static const uptr kHiAppMemBeg = 0x7d00000000ull;
179 static const uptr kHiAppMemEnd = 0x7fffffffffull;
180 static const uptr kShadowMsk = 0x7000000000ull;
181 static const uptr kShadowXor = 0x1000000000ull;
182 static const uptr kShadowAdd = 0x0000000000ull;
183 static const uptr kVdsoBeg = 0x7f00000000ull;
184 };
185
186 /*
187 C/C++ on linux/aarch64 (42-bit VMA)
188 00000 0010 00 - 02000 0000 00: main binary (128 GB)
189 02000 0000 00 - 08000 0000 00: -
190 10000 0000 00 - 20000 0000 00: shadow memory (1024 GB)
191 20000 0000 00 - 24000 0000 00: metainfo (256 GB)
192 24000 0000 00 - 2aa00 0000 00: -
193 2aa00 0000 00 - 2c000 0000 00: main binary (PIE) (88 GB)
194 2c000 0000 00 - 3c000 0000 00: -
195 3c000 0000 00 - 3f000 0000 00: heap (192 GB)
196 3f000 0000 00 - 3ffff ffff ff: modules and main thread stack (64 GB)
197 */
198 struct MappingAarch64_42 {
199 static const uptr kLoAppMemBeg = 0x00000001000ull;
200 static const uptr kLoAppMemEnd = 0x02000000000ull;
201 static const uptr kShadowBeg = 0x10000000000ull;
202 static const uptr kShadowEnd = 0x20000000000ull;
203 static const uptr kMetaShadowBeg = 0x20000000000ull;
204 static const uptr kMetaShadowEnd = 0x24000000000ull;
205 static const uptr kMidAppMemBeg = 0x2aa00000000ull;
206 static const uptr kMidAppMemEnd = 0x2c000000000ull;
207 static const uptr kHeapMemBeg = 0x3c000000000ull;
208 static const uptr kHeapMemEnd = 0x3f000000000ull;
209 static const uptr kHiAppMemBeg = 0x3f000000000ull;
210 static const uptr kHiAppMemEnd = 0x3ffffffffffull;
211 static const uptr kShadowMsk = 0x38000000000ull;
212 static const uptr kShadowXor = 0x08000000000ull;
213 static const uptr kShadowAdd = 0x00000000000ull;
214 static const uptr kVdsoBeg = 0x37f00000000ull;
215 };
216
217 /*
218 C/C++ on linux/aarch64 (48-bit VMA)
219 0000 0000 1000 - 0a00 0000 0000: main binary (10240 GB)
220 0a00 0000 1000 - 1554 0000 0000: -
221 1554 0000 1000 - 5400 0000 0000: shadow memory (64176 GB)
222 5400 0000 1000 - 8000 0000 0000: -
223 8000 0000 1000 - 0a00 0000 0000: metainfo (32768 GB)
224 a000 0000 1000 - aaaa 0000 0000: -
225 aaaa 0000 1000 - ac00 0000 0000: main binary (PIE) (1368 GB)
226 ac00 0000 1000 - fc00 0000 0000: -
227 fc00 0000 1000 - ffff ffff ffff: modules and main thread stack (4096 GB)
228
229 N.B. the shadow memory region has a strange start address, because it
230 contains the shadows for the mid, high and low app regions (in this
231 unusual order).
232 */
233 struct MappingAarch64_48 {
234 static const uptr kLoAppMemBeg = 0x0000000001000ull;
235 static const uptr kLoAppMemEnd = 0x00a0000000000ull;
236 static const uptr kShadowBeg = 0x0155400000000ull;
237 static const uptr kShadowEnd = 0x0540000000000ull;
238 static const uptr kMetaShadowBeg = 0x0800000000000ull;
239 static const uptr kMetaShadowEnd = 0x0a00000000000ull;
240 static const uptr kMidAppMemBeg = 0x0aaaa00000000ull;
241 static const uptr kMidAppMemEnd = 0x0ac0000000000ull;
242 static const uptr kHiAppMemBeg = 0x0fc0000000000ull;
243 static const uptr kHiAppMemEnd = 0x1000000000000ull;
244 static const uptr kHeapMemBeg = 0x0fc0000000000ull;
245 static const uptr kHeapMemEnd = 0x0fc0000000000ull;
246 static const uptr kShadowMsk = 0x0c00000000000ull;
247 static const uptr kShadowXor = 0x0200000000000ull;
248 static const uptr kShadowAdd = 0x0000000000000ull;
249 static const uptr kVdsoBeg = 0xffff000000000ull;
250 };
251
252 /* C/C++ on linux/loongarch64 (47-bit VMA)
253 0000 0000 4000 - 0080 0000 0000: main binary
254 0080 0000 0000 - 0100 0000 0000: -
255 0100 0000 0000 - 1000 0000 0000: shadow memory
256 1000 0000 0000 - 3000 0000 0000: -
257 3000 0000 0000 - 3400 0000 0000: metainfo
258 3400 0000 0000 - 5555 0000 0000: -
259 5555 0000 0000 - 5556 0000 0000: main binary (PIE)
260 5556 0000 0000 - 7ffe 0000 0000: -
261 7ffe 0000 0000 - 7fff 0000 0000: heap
262 7fff 0000 0000 - 7fff 8000 0000: -
263 7fff 8000 0000 - 8000 0000 0000: modules and main thread stack
264 */
265 struct MappingLoongArch64_47 {
266 static const uptr kMetaShadowBeg = 0x300000000000ull;
267 static const uptr kMetaShadowEnd = 0x340000000000ull;
268 static const uptr kShadowBeg = 0x010000000000ull;
269 static const uptr kShadowEnd = 0x100000000000ull;
270 static const uptr kHeapMemBeg = 0x7ffe00000000ull;
271 static const uptr kHeapMemEnd = 0x7fff00000000ull;
272 static const uptr kLoAppMemBeg = 0x000000004000ull;
273 static const uptr kLoAppMemEnd = 0x008000000000ull;
274 static const uptr kMidAppMemBeg = 0x555500000000ull;
275 static const uptr kMidAppMemEnd = 0x555600000000ull;
276 static const uptr kHiAppMemBeg = 0x7fff80000000ull;
277 static const uptr kHiAppMemEnd = 0x800000000000ull;
278 static const uptr kShadowMsk = 0x780000000000ull;
279 static const uptr kShadowXor = 0x040000000000ull;
280 static const uptr kShadowAdd = 0x000000000000ull;
281 static const uptr kVdsoBeg = 0x7fffffffc000ull;
282 };
283
284 /*
285 C/C++ on linux/powerpc64 (44-bit VMA)
286 0000 0000 0100 - 0001 0000 0000: main binary
287 0001 0000 0000 - 0001 0000 0000: -
288 0001 0000 0000 - 0b00 0000 0000: shadow
289 0b00 0000 0000 - 0b00 0000 0000: -
290 0b00 0000 0000 - 0d00 0000 0000: metainfo (memory blocks and sync objects)
291 0d00 0000 0000 - 0f00 0000 0000: -
292 0f00 0000 0000 - 0f50 0000 0000: heap
293 0f50 0000 0000 - 0f60 0000 0000: -
294 0f60 0000 0000 - 1000 0000 0000: modules and main thread stack
295 */
296 struct MappingPPC64_44 {
297 static const uptr kBroken = kBrokenMapping | kBrokenReverseMapping |
298 kBrokenLinearity | kBrokenAliasedMetas;
299 static const uptr kMetaShadowBeg = 0x0b0000000000ull;
300 static const uptr kMetaShadowEnd = 0x0d0000000000ull;
301 static const uptr kShadowBeg = 0x000100000000ull;
302 static const uptr kShadowEnd = 0x0b0000000000ull;
303 static const uptr kLoAppMemBeg = 0x000000000100ull;
304 static const uptr kLoAppMemEnd = 0x000100000000ull;
305 static const uptr kHeapMemBeg = 0x0f0000000000ull;
306 static const uptr kHeapMemEnd = 0x0f5000000000ull;
307 static const uptr kHiAppMemBeg = 0x0f6000000000ull;
308 static const uptr kHiAppMemEnd = 0x100000000000ull; // 44 bits
309 static const uptr kShadowMsk = 0x0f0000000000ull;
310 static const uptr kShadowXor = 0x002100000000ull;
311 static const uptr kShadowAdd = 0x000000000000ull;
312 static const uptr kVdsoBeg = 0x3c0000000000000ull;
313 static const uptr kMidAppMemBeg = 0;
314 static const uptr kMidAppMemEnd = 0;
315 };
316
317 /*
318 C/C++ on linux/powerpc64 (46-bit VMA)
319 0000 0000 1000 - 0100 0000 0000: main binary
320 0100 0000 0000 - 0200 0000 0000: -
321 0100 0000 0000 - 0800 0000 0000: shadow
322 0800 0000 0000 - 1000 0000 0000: -
323 1000 0000 0000 - 1200 0000 0000: metainfo (memory blocks and sync objects)
324 1200 0000 0000 - 3d00 0000 0000: -
325 3d00 0000 0000 - 3e00 0000 0000: heap
326 3e00 0000 0000 - 3e80 0000 0000: -
327 3e80 0000 0000 - 4000 0000 0000: modules and main thread stack
328 */
329 struct MappingPPC64_46 {
330 static const uptr kMetaShadowBeg = 0x100000000000ull;
331 static const uptr kMetaShadowEnd = 0x120000000000ull;
332 static const uptr kShadowBeg = 0x010000000000ull;
333 static const uptr kShadowEnd = 0x080000000000ull;
334 static const uptr kHeapMemBeg = 0x3d0000000000ull;
335 static const uptr kHeapMemEnd = 0x3e0000000000ull;
336 static const uptr kLoAppMemBeg = 0x000000001000ull;
337 static const uptr kLoAppMemEnd = 0x010000000000ull;
338 static const uptr kHiAppMemBeg = 0x3e8000000000ull;
339 static const uptr kHiAppMemEnd = 0x400000000000ull; // 46 bits
340 static const uptr kShadowMsk = 0x3c0000000000ull;
341 static const uptr kShadowXor = 0x020000000000ull;
342 static const uptr kShadowAdd = 0x000000000000ull;
343 static const uptr kVdsoBeg = 0x7800000000000000ull;
344 static const uptr kMidAppMemBeg = 0;
345 static const uptr kMidAppMemEnd = 0;
346 };
347
348 /*
349 C/C++ on linux/powerpc64 (47-bit VMA)
350 0000 0000 1000 - 0100 0000 0000: main binary
351 0100 0000 0000 - 0200 0000 0000: -
352 0100 0000 0000 - 0800 0000 0000: shadow
353 0800 0000 0000 - 1000 0000 0000: -
354 1000 0000 0000 - 1200 0000 0000: metainfo (memory blocks and sync objects)
355 1200 0000 0000 - 7d00 0000 0000: -
356 7d00 0000 0000 - 7e00 0000 0000: heap
357 7e00 0000 0000 - 7e80 0000 0000: -
358 7e80 0000 0000 - 8000 0000 0000: modules and main thread stack
359 */
360 struct MappingPPC64_47 {
361 static const uptr kMetaShadowBeg = 0x100000000000ull;
362 static const uptr kMetaShadowEnd = 0x120000000000ull;
363 static const uptr kShadowBeg = 0x010000000000ull;
364 static const uptr kShadowEnd = 0x080000000000ull;
365 static const uptr kHeapMemBeg = 0x7d0000000000ull;
366 static const uptr kHeapMemEnd = 0x7e0000000000ull;
367 static const uptr kLoAppMemBeg = 0x000000001000ull;
368 static const uptr kLoAppMemEnd = 0x010000000000ull;
369 static const uptr kHiAppMemBeg = 0x7e8000000000ull;
370 static const uptr kHiAppMemEnd = 0x800000000000ull; // 47 bits
371 static const uptr kShadowMsk = 0x7c0000000000ull;
372 static const uptr kShadowXor = 0x020000000000ull;
373 static const uptr kShadowAdd = 0x000000000000ull;
374 static const uptr kVdsoBeg = 0x7800000000000000ull;
375 static const uptr kMidAppMemBeg = 0;
376 static const uptr kMidAppMemEnd = 0;
377 };
378
379 /*
380 C/C++ on linux/riscv64 (39-bit VMA)
381 0000 0010 00 - 0200 0000 00: main binary ( 8 GB)
382 0200 0000 00 - 1000 0000 00: -
383 1000 0000 00 - 4000 0000 00: shadow memory (64 GB)
384 4000 0000 00 - 4800 0000 00: metainfo (16 GB)
385 4800 0000 00 - 5500 0000 00: -
386 5500 0000 00 - 5a00 0000 00: main binary (PIE) (~8 GB)
387 5600 0000 00 - 7c00 0000 00: -
388 7d00 0000 00 - 7fff ffff ff: libraries and main thread stack ( 8 GB)
389
390 mmap by default allocates from top downwards
391 VDSO sits below loader and above dynamic libraries, within HiApp region.
392 Heap starts after program region whose position depends on pie or non-pie.
393 Disable tracking them since their locations are not fixed.
394 */
395 struct MappingRiscv64_39 {
396 static const uptr kLoAppMemBeg = 0x0000001000ull;
397 static const uptr kLoAppMemEnd = 0x0200000000ull;
398 static const uptr kShadowBeg = 0x1000000000ull;
399 static const uptr kShadowEnd = 0x2000000000ull;
400 static const uptr kMetaShadowBeg = 0x2000000000ull;
401 static const uptr kMetaShadowEnd = 0x2400000000ull;
402 static const uptr kMidAppMemBeg = 0x2aaaaaa000ull;
403 static const uptr kMidAppMemEnd = 0x2c00000000ull;
404 static const uptr kHeapMemBeg = 0x2c00000000ull;
405 static const uptr kHeapMemEnd = 0x2c00000000ull;
406 static const uptr kHiAppMemBeg = 0x3c00000000ull;
407 static const uptr kHiAppMemEnd = 0x3fffffffffull;
408 static const uptr kShadowMsk = 0x3800000000ull;
409 static const uptr kShadowXor = 0x0800000000ull;
410 static const uptr kShadowAdd = 0x0000000000ull;
411 static const uptr kVdsoBeg = 0x4000000000ull;
412 };
413
414 /*
415 C/C++ on linux/riscv64 (48-bit VMA)
416 0000 0000 1000 - 0400 0000 0000: main binary ( 4 TB)
417 0500 0000 0000 - 2000 0000 0000: -
418 2000 0000 0000 - 4000 0000 0000: shadow memory (32 TB)
419 4000 0000 0000 - 4800 0000 0000: metainfo ( 8 TB)
420 4800 0000 0000 - 5555 5555 5000: -
421 5555 5555 5000 - 5a00 0000 0000: main binary (PIE) (~5 TB)
422 5a00 0000 0000 - 7a00 0000 0000: -
423 7a00 0000 0000 - 7fff ffff ffff: libraries and main thread stack ( 6 TB)
424 */
425 struct MappingRiscv64_48 {
426 static const uptr kLoAppMemBeg = 0x000000001000ull;
427 static const uptr kLoAppMemEnd = 0x040000000000ull;
428 static const uptr kShadowBeg = 0x200000000000ull;
429 static const uptr kShadowEnd = 0x400000000000ull;
430 static const uptr kMetaShadowBeg = 0x400000000000ull;
431 static const uptr kMetaShadowEnd = 0x480000000000ull;
432 static const uptr kMidAppMemBeg = 0x555555555000ull;
433 static const uptr kMidAppMemEnd = 0x5a0000000000ull;
434 static const uptr kHeapMemBeg = 0x5a0000000000ull;
435 static const uptr kHeapMemEnd = 0x5a0000000000ull;
436 static const uptr kHiAppMemBeg = 0x7a0000000000ull;
437 static const uptr kHiAppMemEnd = 0x7fffffffffffull;
438 static const uptr kShadowMsk = 0x700000000000ull;
439 static const uptr kShadowXor = 0x100000000000ull;
440 static const uptr kShadowAdd = 0x000000000000ull;
441 static const uptr kVdsoBeg = 0x800000000000ull;
442 };
443
444 /*
445 C/C++ on linux/s390x
446 While the kernel provides a 64-bit address space, we have to restrict ourselves
447 to 48 bits due to how e.g. SyncVar::GetId() works.
448 0000 0000 1000 - 0e00 0000 0000: binary, modules, stacks - 14 TiB
449 0e00 0000 0000 - 2000 0000 0000: -
450 2000 0000 0000 - 4000 0000 0000: shadow - 32TiB (2 * app)
451 4000 0000 0000 - 9000 0000 0000: -
452 9000 0000 0000 - 9800 0000 0000: metainfo - 8TiB (0.5 * app)
453 9800 0000 0000 - be00 0000 0000: -
454 be00 0000 0000 - c000 0000 0000: heap - 2TiB (max supported by the allocator)
455 */
456 struct MappingS390x {
457 static const uptr kMetaShadowBeg = 0x900000000000ull;
458 static const uptr kMetaShadowEnd = 0x980000000000ull;
459 static const uptr kShadowBeg = 0x200000000000ull;
460 static const uptr kShadowEnd = 0x400000000000ull;
461 static const uptr kHeapMemBeg = 0xbe0000000000ull;
462 static const uptr kHeapMemEnd = 0xc00000000000ull;
463 static const uptr kLoAppMemBeg = 0x000000001000ull;
464 static const uptr kLoAppMemEnd = 0x0e0000000000ull;
465 static const uptr kHiAppMemBeg = 0xc00000004000ull;
466 static const uptr kHiAppMemEnd = 0xc00000004000ull;
467 static const uptr kShadowMsk = 0xb00000000000ull;
468 static const uptr kShadowXor = 0x100000000000ull;
469 static const uptr kShadowAdd = 0x000000000000ull;
470 static const uptr kVdsoBeg = 0xfffffffff000ull;
471 static const uptr kMidAppMemBeg = 0;
472 static const uptr kMidAppMemEnd = 0;
473 };
474
475 /* Go on linux, darwin and freebsd on x86_64
476 0000 0000 1000 - 0000 1000 0000: executable
477 0000 1000 0000 - 00c0 0000 0000: -
478 00c0 0000 0000 - 00e0 0000 0000: heap
479 00e0 0000 0000 - 2000 0000 0000: -
480 2000 0000 0000 - 21c0 0000 0000: shadow
481 21c0 0000 0000 - 3000 0000 0000: -
482 3000 0000 0000 - 4000 0000 0000: metainfo (memory blocks and sync objects)
483 4000 0000 0000 - 8000 0000 0000: -
484 */
485
486 struct MappingGo48 {
487 static const uptr kMetaShadowBeg = 0x300000000000ull;
488 static const uptr kMetaShadowEnd = 0x400000000000ull;
489 static const uptr kShadowBeg = 0x200000000000ull;
490 static const uptr kShadowEnd = 0x21c000000000ull;
491 static const uptr kLoAppMemBeg = 0x000000001000ull;
492 static const uptr kLoAppMemEnd = 0x00e000000000ull;
493 static const uptr kMidAppMemBeg = 0;
494 static const uptr kMidAppMemEnd = 0;
495 static const uptr kHiAppMemBeg = 0;
496 static const uptr kHiAppMemEnd = 0;
497 static const uptr kHeapMemBeg = 0;
498 static const uptr kHeapMemEnd = 0;
499 static const uptr kVdsoBeg = 0;
500 static const uptr kShadowMsk = 0;
501 static const uptr kShadowXor = 0;
502 static const uptr kShadowAdd = 0x200000000000ull;
503 };
504
505 /* Go on windows
506 0000 0000 1000 - 0000 1000 0000: executable
507 0000 1000 0000 - 00f8 0000 0000: -
508 00c0 0000 0000 - 00e0 0000 0000: heap
509 00e0 0000 0000 - 0100 0000 0000: -
510 0100 0000 0000 - 0300 0000 0000: shadow
511 0300 0000 0000 - 0700 0000 0000: -
512 0700 0000 0000 - 0770 0000 0000: metainfo (memory blocks and sync objects)
513 07d0 0000 0000 - 8000 0000 0000: -
514 PIE binaries currently not supported, but it should be theoretically possible.
515 */
516
517 struct MappingGoWindows {
518 static const uptr kMetaShadowBeg = 0x070000000000ull;
519 static const uptr kMetaShadowEnd = 0x077000000000ull;
520 static const uptr kShadowBeg = 0x010000000000ull;
521 static const uptr kShadowEnd = 0x030000000000ull;
522 static const uptr kLoAppMemBeg = 0x000000001000ull;
523 static const uptr kLoAppMemEnd = 0x00e000000000ull;
524 static const uptr kMidAppMemBeg = 0;
525 static const uptr kMidAppMemEnd = 0;
526 static const uptr kHiAppMemBeg = 0;
527 static const uptr kHiAppMemEnd = 0;
528 static const uptr kHeapMemBeg = 0;
529 static const uptr kHeapMemEnd = 0;
530 static const uptr kVdsoBeg = 0;
531 static const uptr kShadowMsk = 0;
532 static const uptr kShadowXor = 0;
533 static const uptr kShadowAdd = 0x010000000000ull;
534 };
535
536 /* Go on linux/powerpc64 (46-bit VMA)
537 0000 0000 1000 - 0000 1000 0000: executable
538 0000 1000 0000 - 00c0 0000 0000: -
539 00c0 0000 0000 - 00e0 0000 0000: heap
540 00e0 0000 0000 - 2000 0000 0000: -
541 2000 0000 0000 - 21c0 0000 0000: shadow
542 21c0 0000 0000 - 2400 0000 0000: -
543 2400 0000 0000 - 2470 0000 0000: metainfo (memory blocks and sync objects)
544 2470 0000 0000 - 4000 0000 0000: -
545 */
546
547 struct MappingGoPPC64_46 {
548 static const uptr kMetaShadowBeg = 0x240000000000ull;
549 static const uptr kMetaShadowEnd = 0x247000000000ull;
550 static const uptr kShadowBeg = 0x200000000000ull;
551 static const uptr kShadowEnd = 0x21c000000000ull;
552 static const uptr kLoAppMemBeg = 0x000000001000ull;
553 static const uptr kLoAppMemEnd = 0x00e000000000ull;
554 static const uptr kMidAppMemBeg = 0;
555 static const uptr kMidAppMemEnd = 0;
556 static const uptr kHiAppMemBeg = 0;
557 static const uptr kHiAppMemEnd = 0;
558 static const uptr kHeapMemBeg = 0;
559 static const uptr kHeapMemEnd = 0;
560 static const uptr kVdsoBeg = 0;
561 static const uptr kShadowMsk = 0;
562 static const uptr kShadowXor = 0;
563 static const uptr kShadowAdd = 0x200000000000ull;
564 };
565
566 /* Go on linux/powerpc64 (47-bit VMA)
567 0000 0000 1000 - 0000 1000 0000: executable
568 0000 1000 0000 - 00c0 0000 0000: -
569 00c0 0000 0000 - 00e0 0000 0000: heap
570 00e0 0000 0000 - 2000 0000 0000: -
571 2000 0000 0000 - 2800 0000 0000: shadow
572 2800 0000 0000 - 3000 0000 0000: -
573 3000 0000 0000 - 3200 0000 0000: metainfo (memory blocks and sync objects)
574 3200 0000 0000 - 8000 0000 0000: -
575 */
576
577 struct MappingGoPPC64_47 {
578 static const uptr kMetaShadowBeg = 0x300000000000ull;
579 static const uptr kMetaShadowEnd = 0x320000000000ull;
580 static const uptr kShadowBeg = 0x200000000000ull;
581 static const uptr kShadowEnd = 0x280000000000ull;
582 static const uptr kLoAppMemBeg = 0x000000001000ull;
583 static const uptr kLoAppMemEnd = 0x00e000000000ull;
584 static const uptr kMidAppMemBeg = 0;
585 static const uptr kMidAppMemEnd = 0;
586 static const uptr kHiAppMemBeg = 0;
587 static const uptr kHiAppMemEnd = 0;
588 static const uptr kHeapMemBeg = 0;
589 static const uptr kHeapMemEnd = 0;
590 static const uptr kVdsoBeg = 0;
591 static const uptr kShadowMsk = 0;
592 static const uptr kShadowXor = 0;
593 static const uptr kShadowAdd = 0x200000000000ull;
594 };
595
596 /* Go on linux/aarch64 (48-bit VMA) and darwin/aarch64 (47-bit VMA)
597 0000 0000 1000 - 0000 1000 0000: executable
598 0000 1000 0000 - 00c0 0000 0000: -
599 00c0 0000 0000 - 00e0 0000 0000: heap
600 00e0 0000 0000 - 2000 0000 0000: -
601 2000 0000 0000 - 2800 0000 0000: shadow
602 2800 0000 0000 - 3000 0000 0000: -
603 3000 0000 0000 - 3200 0000 0000: metainfo (memory blocks and sync objects)
604 3200 0000 0000 - 8000 0000 0000: -
605 */
606 struct MappingGoAarch64 {
607 static const uptr kMetaShadowBeg = 0x300000000000ull;
608 static const uptr kMetaShadowEnd = 0x320000000000ull;
609 static const uptr kShadowBeg = 0x200000000000ull;
610 static const uptr kShadowEnd = 0x280000000000ull;
611 static const uptr kLoAppMemBeg = 0x000000001000ull;
612 static const uptr kLoAppMemEnd = 0x00e000000000ull;
613 static const uptr kMidAppMemBeg = 0;
614 static const uptr kMidAppMemEnd = 0;
615 static const uptr kHiAppMemBeg = 0;
616 static const uptr kHiAppMemEnd = 0;
617 static const uptr kHeapMemBeg = 0;
618 static const uptr kHeapMemEnd = 0;
619 static const uptr kVdsoBeg = 0;
620 static const uptr kShadowMsk = 0;
621 static const uptr kShadowXor = 0;
622 static const uptr kShadowAdd = 0x200000000000ull;
623 };
624
625 /* Go on linux/loongarch64 (47-bit VMA)
626 0000 0000 1000 - 0000 1000 0000: executable
627 0000 1000 0000 - 00c0 0000 0000: -
628 00c0 0000 0000 - 00e0 0000 0000: heap
629 00e0 0000 0000 - 2000 0000 0000: -
630 2000 0000 0000 - 2800 0000 0000: shadow
631 2800 0000 0000 - 3000 0000 0000: -
632 3000 0000 0000 - 3200 0000 0000: metainfo (memory blocks and sync objects)
633 3200 0000 0000 - 8000 0000 0000: -
634 */
635 struct MappingGoLoongArch64_47 {
636 static const uptr kMetaShadowBeg = 0x300000000000ull;
637 static const uptr kMetaShadowEnd = 0x320000000000ull;
638 static const uptr kShadowBeg = 0x200000000000ull;
639 static const uptr kShadowEnd = 0x280000000000ull;
640 static const uptr kLoAppMemBeg = 0x000000001000ull;
641 static const uptr kLoAppMemEnd = 0x00e000000000ull;
642 static const uptr kMidAppMemBeg = 0;
643 static const uptr kMidAppMemEnd = 0;
644 static const uptr kHiAppMemBeg = 0;
645 static const uptr kHiAppMemEnd = 0;
646 static const uptr kHeapMemBeg = 0;
647 static const uptr kHeapMemEnd = 0;
648 static const uptr kVdsoBeg = 0;
649 static const uptr kShadowMsk = 0;
650 static const uptr kShadowXor = 0;
651 static const uptr kShadowAdd = 0x200000000000ull;
652 };
653
654 /*
655 Go on linux/mips64 (47-bit VMA)
656 0000 0000 1000 - 0000 1000 0000: executable
657 0000 1000 0000 - 00c0 0000 0000: -
658 00c0 0000 0000 - 00e0 0000 0000: heap
659 00e0 0000 0000 - 2000 0000 0000: -
660 2000 0000 0000 - 2800 0000 0000: shadow
661 2800 0000 0000 - 3000 0000 0000: -
662 3000 0000 0000 - 3200 0000 0000: metainfo (memory blocks and sync objects)
663 3200 0000 0000 - 8000 0000 0000: -
664 */
665 struct MappingGoMips64_47 {
666 static const uptr kMetaShadowBeg = 0x300000000000ull;
667 static const uptr kMetaShadowEnd = 0x320000000000ull;
668 static const uptr kShadowBeg = 0x200000000000ull;
669 static const uptr kShadowEnd = 0x280000000000ull;
670 static const uptr kLoAppMemBeg = 0x000000001000ull;
671 static const uptr kLoAppMemEnd = 0x00e000000000ull;
672 static const uptr kMidAppMemBeg = 0;
673 static const uptr kMidAppMemEnd = 0;
674 static const uptr kHiAppMemBeg = 0;
675 static const uptr kHiAppMemEnd = 0;
676 static const uptr kHeapMemBeg = 0;
677 static const uptr kHeapMemEnd = 0;
678 static const uptr kVdsoBeg = 0;
679 static const uptr kShadowMsk = 0;
680 static const uptr kShadowXor = 0;
681 static const uptr kShadowAdd = 0x200000000000ull;
682 };
683
684 /* Go on linux/riscv64 (48-bit VMA)
685 0000 0001 0000 - 00e0 0000 0000: executable and heap (896 GiB)
686 00e0 0000 0000 - 2000 0000 0000: -
687 2000 0000 0000 - 2400 0000 0000: shadow - 4 TiB ( ~ 4 * app)
688 2400 0000 0000 - 3000 0000 0000: -
689 3000 0000 0000 - 3100 0000 0000: metainfo - 1 TiB ( ~ 1 * app)
690 3100 0000 0000 - 8000 0000 0000: -
691 */
692 struct MappingGoRiscv64 {
693 static const uptr kMetaShadowBeg = 0x300000000000ull;
694 static const uptr kMetaShadowEnd = 0x310000000000ull;
695 static const uptr kShadowBeg = 0x200000000000ull;
696 static const uptr kShadowEnd = 0x240000000000ull;
697 static const uptr kLoAppMemBeg = 0x000000010000ull;
698 static const uptr kLoAppMemEnd = 0x000e00000000ull;
699 static const uptr kMidAppMemBeg = 0;
700 static const uptr kMidAppMemEnd = 0;
701 static const uptr kHiAppMemBeg = 0;
702 static const uptr kHiAppMemEnd = 0;
703 static const uptr kHeapMemBeg = 0;
704 static const uptr kHeapMemEnd = 0;
705 static const uptr kVdsoBeg = 0;
706 static const uptr kShadowMsk = 0;
707 static const uptr kShadowXor = 0;
708 static const uptr kShadowAdd = 0x200000000000ull;
709 };
710
711 /*
712 Go on linux/s390x
713 0000 0000 1000 - 1000 0000 0000: executable and heap - 16 TiB
714 1000 0000 0000 - 4000 0000 0000: -
715 4000 0000 0000 - 6000 0000 0000: shadow - 64TiB (4 * app)
716 6000 0000 0000 - 9000 0000 0000: -
717 9000 0000 0000 - 9800 0000 0000: metainfo - 8TiB (0.5 * app)
718 */
719 struct MappingGoS390x {
720 static const uptr kMetaShadowBeg = 0x900000000000ull;
721 static const uptr kMetaShadowEnd = 0x980000000000ull;
722 static const uptr kShadowBeg = 0x400000000000ull;
723 static const uptr kShadowEnd = 0x600000000000ull;
724 static const uptr kLoAppMemBeg = 0x000000001000ull;
725 static const uptr kLoAppMemEnd = 0x100000000000ull;
726 static const uptr kMidAppMemBeg = 0;
727 static const uptr kMidAppMemEnd = 0;
728 static const uptr kHiAppMemBeg = 0;
729 static const uptr kHiAppMemEnd = 0;
730 static const uptr kHeapMemBeg = 0;
731 static const uptr kHeapMemEnd = 0;
732 static const uptr kVdsoBeg = 0;
733 static const uptr kShadowMsk = 0;
734 static const uptr kShadowXor = 0;
735 static const uptr kShadowAdd = 0x400000000000ull;
736 };
737
738 extern uptr vmaSize;
739
740 template <typename Func, typename Arg>
SelectMapping(Arg arg)741 ALWAYS_INLINE auto SelectMapping(Arg arg) {
742 #if SANITIZER_GO
743 # if defined(__powerpc64__)
744 switch (vmaSize) {
745 case 46:
746 return Func::template Apply<MappingGoPPC64_46>(arg);
747 case 47:
748 return Func::template Apply<MappingGoPPC64_47>(arg);
749 }
750 # elif defined(__mips64)
751 return Func::template Apply<MappingGoMips64_47>(arg);
752 # elif defined(__s390x__)
753 return Func::template Apply<MappingGoS390x>(arg);
754 # elif defined(__aarch64__)
755 return Func::template Apply<MappingGoAarch64>(arg);
756 # elif defined(__loongarch_lp64)
757 return Func::template Apply<MappingGoLoongArch64_47>(arg);
758 # elif SANITIZER_RISCV64
759 return Func::template Apply<MappingGoRiscv64>(arg);
760 # elif SANITIZER_WINDOWS
761 return Func::template Apply<MappingGoWindows>(arg);
762 # else
763 return Func::template Apply<MappingGo48>(arg);
764 # endif
765 #else // SANITIZER_GO
766 # if SANITIZER_IOS && !SANITIZER_IOSSIM
767 return Func::template Apply<MappingAppleAarch64>(arg);
768 # elif defined(__x86_64__) || SANITIZER_APPLE
769 return Func::template Apply<Mapping48AddressSpace>(arg);
770 # elif defined(__aarch64__)
771 switch (vmaSize) {
772 case 39:
773 return Func::template Apply<MappingAarch64_39>(arg);
774 case 42:
775 return Func::template Apply<MappingAarch64_42>(arg);
776 case 48:
777 return Func::template Apply<MappingAarch64_48>(arg);
778 }
779 # elif SANITIZER_LOONGARCH64
780 return Func::template Apply<MappingLoongArch64_47>(arg);
781 # elif defined(__powerpc64__)
782 switch (vmaSize) {
783 case 44:
784 return Func::template Apply<MappingPPC64_44>(arg);
785 case 46:
786 return Func::template Apply<MappingPPC64_46>(arg);
787 case 47:
788 return Func::template Apply<MappingPPC64_47>(arg);
789 }
790 # elif defined(__mips64)
791 return Func::template Apply<MappingMips64_40>(arg);
792 # elif SANITIZER_RISCV64
793 switch (vmaSize) {
794 case 39:
795 return Func::template Apply<MappingRiscv64_39>(arg);
796 case 48:
797 return Func::template Apply<MappingRiscv64_48>(arg);
798 }
799 # elif defined(__s390x__)
800 return Func::template Apply<MappingS390x>(arg);
801 # else
802 # error "unsupported platform"
803 # endif
804 #endif
805 Die();
806 }
807
808 template <typename Func>
ForEachMapping()809 void ForEachMapping() {
810 Func::template Apply<Mapping48AddressSpace>();
811 Func::template Apply<MappingMips64_40>();
812 Func::template Apply<MappingAppleAarch64>();
813 Func::template Apply<MappingAarch64_39>();
814 Func::template Apply<MappingAarch64_42>();
815 Func::template Apply<MappingAarch64_48>();
816 Func::template Apply<MappingLoongArch64_47>();
817 Func::template Apply<MappingPPC64_44>();
818 Func::template Apply<MappingPPC64_46>();
819 Func::template Apply<MappingPPC64_47>();
820 Func::template Apply<MappingRiscv64_39>();
821 Func::template Apply<MappingRiscv64_48>();
822 Func::template Apply<MappingS390x>();
823 Func::template Apply<MappingGo48>();
824 Func::template Apply<MappingGoWindows>();
825 Func::template Apply<MappingGoPPC64_46>();
826 Func::template Apply<MappingGoPPC64_47>();
827 Func::template Apply<MappingGoAarch64>();
828 Func::template Apply<MappingGoLoongArch64_47>();
829 Func::template Apply<MappingGoMips64_47>();
830 Func::template Apply<MappingGoRiscv64>();
831 Func::template Apply<MappingGoS390x>();
832 }
833
834 enum MappingType {
835 kLoAppMemBeg,
836 kLoAppMemEnd,
837 kHiAppMemBeg,
838 kHiAppMemEnd,
839 kMidAppMemBeg,
840 kMidAppMemEnd,
841 kHeapMemBeg,
842 kHeapMemEnd,
843 kShadowBeg,
844 kShadowEnd,
845 kMetaShadowBeg,
846 kMetaShadowEnd,
847 kVdsoBeg,
848 };
849
850 struct MappingField {
851 template <typename Mapping>
ApplyMappingField852 static uptr Apply(MappingType type) {
853 switch (type) {
854 case kLoAppMemBeg:
855 return Mapping::kLoAppMemBeg;
856 case kLoAppMemEnd:
857 return Mapping::kLoAppMemEnd;
858 case kMidAppMemBeg:
859 return Mapping::kMidAppMemBeg;
860 case kMidAppMemEnd:
861 return Mapping::kMidAppMemEnd;
862 case kHiAppMemBeg:
863 return Mapping::kHiAppMemBeg;
864 case kHiAppMemEnd:
865 return Mapping::kHiAppMemEnd;
866 case kHeapMemBeg:
867 return Mapping::kHeapMemBeg;
868 case kHeapMemEnd:
869 return Mapping::kHeapMemEnd;
870 case kVdsoBeg:
871 return Mapping::kVdsoBeg;
872 case kShadowBeg:
873 return Mapping::kShadowBeg;
874 case kShadowEnd:
875 return Mapping::kShadowEnd;
876 case kMetaShadowBeg:
877 return Mapping::kMetaShadowBeg;
878 case kMetaShadowEnd:
879 return Mapping::kMetaShadowEnd;
880 }
881 Die();
882 }
883 };
884
885 ALWAYS_INLINE
LoAppMemBeg(void)886 uptr LoAppMemBeg(void) { return SelectMapping<MappingField>(kLoAppMemBeg); }
887 ALWAYS_INLINE
LoAppMemEnd(void)888 uptr LoAppMemEnd(void) { return SelectMapping<MappingField>(kLoAppMemEnd); }
889
890 ALWAYS_INLINE
MidAppMemBeg(void)891 uptr MidAppMemBeg(void) { return SelectMapping<MappingField>(kMidAppMemBeg); }
892 ALWAYS_INLINE
MidAppMemEnd(void)893 uptr MidAppMemEnd(void) { return SelectMapping<MappingField>(kMidAppMemEnd); }
894
895 ALWAYS_INLINE
HeapMemBeg(void)896 uptr HeapMemBeg(void) { return SelectMapping<MappingField>(kHeapMemBeg); }
897 ALWAYS_INLINE
HeapMemEnd(void)898 uptr HeapMemEnd(void) { return SelectMapping<MappingField>(kHeapMemEnd); }
899
900 ALWAYS_INLINE
HiAppMemBeg(void)901 uptr HiAppMemBeg(void) { return SelectMapping<MappingField>(kHiAppMemBeg); }
902 ALWAYS_INLINE
HiAppMemEnd(void)903 uptr HiAppMemEnd(void) { return SelectMapping<MappingField>(kHiAppMemEnd); }
904
905 ALWAYS_INLINE
VdsoBeg(void)906 uptr VdsoBeg(void) { return SelectMapping<MappingField>(kVdsoBeg); }
907
908 ALWAYS_INLINE
ShadowBeg(void)909 uptr ShadowBeg(void) { return SelectMapping<MappingField>(kShadowBeg); }
910 ALWAYS_INLINE
ShadowEnd(void)911 uptr ShadowEnd(void) { return SelectMapping<MappingField>(kShadowEnd); }
912
913 ALWAYS_INLINE
MetaShadowBeg(void)914 uptr MetaShadowBeg(void) { return SelectMapping<MappingField>(kMetaShadowBeg); }
915 ALWAYS_INLINE
MetaShadowEnd(void)916 uptr MetaShadowEnd(void) { return SelectMapping<MappingField>(kMetaShadowEnd); }
917
918 struct IsAppMemImpl {
919 template <typename Mapping>
ApplyIsAppMemImpl920 static bool Apply(uptr mem) {
921 return (mem >= Mapping::kHeapMemBeg && mem < Mapping::kHeapMemEnd) ||
922 (mem >= Mapping::kMidAppMemBeg && mem < Mapping::kMidAppMemEnd) ||
923 (mem >= Mapping::kLoAppMemBeg && mem < Mapping::kLoAppMemEnd) ||
924 (mem >= Mapping::kHiAppMemBeg && mem < Mapping::kHiAppMemEnd);
925 }
926 };
927
928 ALWAYS_INLINE
IsAppMem(uptr mem)929 bool IsAppMem(uptr mem) { return SelectMapping<IsAppMemImpl>(mem); }
930
931 struct IsShadowMemImpl {
932 template <typename Mapping>
ApplyIsShadowMemImpl933 static bool Apply(uptr mem) {
934 return mem >= Mapping::kShadowBeg && mem < Mapping::kShadowEnd;
935 }
936 };
937
938 ALWAYS_INLINE
IsShadowMem(RawShadow * p)939 bool IsShadowMem(RawShadow *p) {
940 return SelectMapping<IsShadowMemImpl>(reinterpret_cast<uptr>(p));
941 }
942
943 struct IsMetaMemImpl {
944 template <typename Mapping>
ApplyIsMetaMemImpl945 static bool Apply(uptr mem) {
946 return mem >= Mapping::kMetaShadowBeg && mem < Mapping::kMetaShadowEnd;
947 }
948 };
949
950 ALWAYS_INLINE
IsMetaMem(const u32 * p)951 bool IsMetaMem(const u32 *p) {
952 return SelectMapping<IsMetaMemImpl>(reinterpret_cast<uptr>(p));
953 }
954
955 struct MemToShadowImpl {
956 template <typename Mapping>
ApplyMemToShadowImpl957 static uptr Apply(uptr x) {
958 DCHECK(IsAppMemImpl::Apply<Mapping>(x));
959 return (((x) & ~(Mapping::kShadowMsk | (kShadowCell - 1))) ^
960 Mapping::kShadowXor) *
961 kShadowMultiplier +
962 Mapping::kShadowAdd;
963 }
964 };
965
966 ALWAYS_INLINE
MemToShadow(uptr x)967 RawShadow *MemToShadow(uptr x) {
968 return reinterpret_cast<RawShadow *>(SelectMapping<MemToShadowImpl>(x));
969 }
970
971 struct MemToMetaImpl {
972 template <typename Mapping>
ApplyMemToMetaImpl973 static u32 *Apply(uptr x) {
974 DCHECK(IsAppMemImpl::Apply<Mapping>(x));
975 return (u32 *)(((((x) & ~(Mapping::kShadowMsk | (kMetaShadowCell - 1)))) /
976 kMetaShadowCell * kMetaShadowSize) |
977 Mapping::kMetaShadowBeg);
978 }
979 };
980
981 ALWAYS_INLINE
MemToMeta(uptr x)982 u32 *MemToMeta(uptr x) { return SelectMapping<MemToMetaImpl>(x); }
983
984 struct ShadowToMemImpl {
985 template <typename Mapping>
ApplyShadowToMemImpl986 static uptr Apply(uptr sp) {
987 if (!IsShadowMemImpl::Apply<Mapping>(sp))
988 return 0;
989 // The shadow mapping is non-linear and we've lost some bits, so we don't
990 // have an easy way to restore the original app address. But the mapping is
991 // a bijection, so we try to restore the address as belonging to
992 // low/mid/high range consecutively and see if shadow->app->shadow mapping
993 // gives us the same address.
994 uptr p =
995 ((sp - Mapping::kShadowAdd) / kShadowMultiplier) ^ Mapping::kShadowXor;
996 if (p >= Mapping::kLoAppMemBeg && p < Mapping::kLoAppMemEnd &&
997 MemToShadowImpl::Apply<Mapping>(p) == sp)
998 return p;
999 if (Mapping::kMidAppMemBeg) {
1000 uptr p_mid = p + (Mapping::kMidAppMemBeg & Mapping::kShadowMsk);
1001 if (p_mid >= Mapping::kMidAppMemBeg && p_mid < Mapping::kMidAppMemEnd &&
1002 MemToShadowImpl::Apply<Mapping>(p_mid) == sp)
1003 return p_mid;
1004 }
1005 return p | Mapping::kShadowMsk;
1006 }
1007 };
1008
1009 ALWAYS_INLINE
ShadowToMem(RawShadow * s)1010 uptr ShadowToMem(RawShadow *s) {
1011 return SelectMapping<ShadowToMemImpl>(reinterpret_cast<uptr>(s));
1012 }
1013
1014 // Compresses addr to kCompressedAddrBits stored in least significant bits.
CompressAddr(uptr addr)1015 ALWAYS_INLINE uptr CompressAddr(uptr addr) {
1016 return addr & ((1ull << kCompressedAddrBits) - 1);
1017 }
1018
1019 struct RestoreAddrImpl {
1020 typedef uptr Result;
1021 template <typename Mapping>
ApplyRestoreAddrImpl1022 static Result Apply(uptr addr) {
1023 // To restore the address we go over all app memory ranges and check if top
1024 // 3 bits of the compressed addr match that of the app range. If yes, we
1025 // assume that the compressed address come from that range and restore the
1026 // missing top bits to match the app range address.
1027 const uptr ranges[] = {
1028 Mapping::kLoAppMemBeg, Mapping::kLoAppMemEnd, Mapping::kMidAppMemBeg,
1029 Mapping::kMidAppMemEnd, Mapping::kHiAppMemBeg, Mapping::kHiAppMemEnd,
1030 Mapping::kHeapMemBeg, Mapping::kHeapMemEnd,
1031 };
1032 const uptr indicator = 0x0e0000000000ull;
1033 const uptr ind_lsb = 1ull << LeastSignificantSetBitIndex(indicator);
1034 for (uptr i = 0; i < ARRAY_SIZE(ranges); i += 2) {
1035 uptr beg = ranges[i];
1036 uptr end = ranges[i + 1];
1037 if (beg == end)
1038 continue;
1039 for (uptr p = beg; p < end; p = RoundDown(p + ind_lsb, ind_lsb)) {
1040 if ((addr & indicator) == (p & indicator))
1041 return addr | (p & ~(ind_lsb - 1));
1042 }
1043 }
1044 Printf("ThreadSanitizer: failed to restore address 0x%zx\n", addr);
1045 Die();
1046 }
1047 };
1048
1049 // Restores compressed addr from kCompressedAddrBits to full representation.
1050 // This is called only during reporting and is not performance-critical.
RestoreAddr(uptr addr)1051 inline uptr RestoreAddr(uptr addr) {
1052 return SelectMapping<RestoreAddrImpl>(addr);
1053 }
1054
1055 void InitializePlatform();
1056 void InitializePlatformEarly();
1057 bool CheckAndProtect(bool protect, bool ignore_heap, bool print_warnings);
1058 void InitializeShadowMemoryPlatform();
1059 void WriteMemoryProfile(char *buf, uptr buf_size, u64 uptime_ns);
1060 int ExtractResolvFDs(void *state, int *fds, int nfd);
1061 int ExtractRecvmsgFDs(void *msg, int *fds, int nfd);
1062 uptr ExtractLongJmpSp(uptr *env);
1063 void ImitateTlsWrite(ThreadState *thr, uptr tls_addr, uptr tls_size);
1064
1065 int call_pthread_cancel_with_cleanup(int (*fn)(void *arg),
1066 void (*cleanup)(void *arg), void *arg);
1067
1068 void DestroyThreadState();
1069 void PlatformCleanUpThreadState(ThreadState *thr);
1070
1071 } // namespace __tsan
1072
1073 #endif // TSAN_PLATFORM_H
1074