13cab2bb3Spatrick //===-- tsan_platform.h -----------------------------------------*- C++ -*-===//
23cab2bb3Spatrick //
33cab2bb3Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
43cab2bb3Spatrick // See https://llvm.org/LICENSE.txt for license information.
53cab2bb3Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
63cab2bb3Spatrick //
73cab2bb3Spatrick //===----------------------------------------------------------------------===//
83cab2bb3Spatrick //
93cab2bb3Spatrick // This file is a part of ThreadSanitizer (TSan), a race detector.
103cab2bb3Spatrick //
113cab2bb3Spatrick // Platform-specific code.
123cab2bb3Spatrick //===----------------------------------------------------------------------===//
133cab2bb3Spatrick
143cab2bb3Spatrick #ifndef TSAN_PLATFORM_H
153cab2bb3Spatrick #define TSAN_PLATFORM_H
163cab2bb3Spatrick
173cab2bb3Spatrick #if !defined(__LP64__) && !defined(_WIN64)
183cab2bb3Spatrick # error "Only 64-bit is supported"
193cab2bb3Spatrick #endif
203cab2bb3Spatrick
21*810390e3Srobert #include "sanitizer_common/sanitizer_common.h"
223cab2bb3Spatrick #include "tsan_defs.h"
233cab2bb3Spatrick
243cab2bb3Spatrick namespace __tsan {
253cab2bb3Spatrick
26*810390e3Srobert enum {
27*810390e3Srobert // App memory is not mapped onto shadow memory range.
28*810390e3Srobert kBrokenMapping = 1 << 0,
29*810390e3Srobert // Mapping app memory and back does not produce the same address,
30*810390e3Srobert // this can lead to wrong addresses in reports and potentially
31*810390e3Srobert // other bad consequences.
32*810390e3Srobert kBrokenReverseMapping = 1 << 1,
33*810390e3Srobert // Mapping is non-linear for linear user range.
34*810390e3Srobert // This is bad and can lead to unpredictable memory corruptions, etc
35*810390e3Srobert // because range access functions assume linearity.
36*810390e3Srobert kBrokenLinearity = 1 << 2,
37*810390e3Srobert // Meta for an app region overlaps with the meta of another app region.
38*810390e3Srobert // This is determined by recomputing the individual meta regions for
39*810390e3Srobert // each app region.
40*810390e3Srobert //
41*810390e3Srobert // N.B. There is no "kBrokenReverseMetaMapping" constant because there
42*810390e3Srobert // is no MetaToMem function. However, note that (!kBrokenLinearity
43*810390e3Srobert // && !kBrokenAliasedMetas) implies that MemToMeta is invertible.
44*810390e3Srobert kBrokenAliasedMetas = 1 << 3,
45*810390e3Srobert };
46d89ec533Spatrick
473cab2bb3Spatrick /*
483cab2bb3Spatrick C/C++ on linux/x86_64 and freebsd/x86_64
493cab2bb3Spatrick 0000 0000 1000 - 0080 0000 0000: main binary and/or MAP_32BIT mappings (512GB)
503cab2bb3Spatrick 0040 0000 0000 - 0100 0000 0000: -
51*810390e3Srobert 0100 0000 0000 - 1000 0000 0000: shadow
52*810390e3Srobert 1000 0000 0000 - 3000 0000 0000: -
533cab2bb3Spatrick 3000 0000 0000 - 4000 0000 0000: metainfo (memory blocks and sync objects)
543cab2bb3Spatrick 4000 0000 0000 - 5500 0000 0000: -
553cab2bb3Spatrick 5500 0000 0000 - 5680 0000 0000: pie binaries without ASLR or on 4.1+ kernels
56*810390e3Srobert 5680 0000 0000 - 7d00 0000 0000: -
573cab2bb3Spatrick 7b00 0000 0000 - 7c00 0000 0000: heap
583cab2bb3Spatrick 7c00 0000 0000 - 7e80 0000 0000: -
593cab2bb3Spatrick 7e80 0000 0000 - 8000 0000 0000: modules and main thread stack
603cab2bb3Spatrick
613cab2bb3Spatrick C/C++ on netbsd/amd64 can reuse the same mapping:
623cab2bb3Spatrick * The address space starts from 0x1000 (option with 0x0) and ends with
633cab2bb3Spatrick 0x7f7ffffff000.
643cab2bb3Spatrick * LoAppMem-kHeapMemEnd can be reused as it is.
653cab2bb3Spatrick * No VDSO support.
663cab2bb3Spatrick * No MidAppMem region.
673cab2bb3Spatrick * No additional HeapMem region.
683cab2bb3Spatrick * HiAppMem contains the stack, loader, shared libraries and heap.
693cab2bb3Spatrick * Stack on NetBSD/amd64 has prereserved 128MB.
703cab2bb3Spatrick * Heap grows downwards (top-down).
713cab2bb3Spatrick * ASLR must be disabled per-process or globally.
723cab2bb3Spatrick */
73*810390e3Srobert struct Mapping48AddressSpace {
743cab2bb3Spatrick static const uptr kMetaShadowBeg = 0x300000000000ull;
753cab2bb3Spatrick static const uptr kMetaShadowEnd = 0x340000000000ull;
763cab2bb3Spatrick static const uptr kShadowBeg = 0x010000000000ull;
77*810390e3Srobert static const uptr kShadowEnd = 0x100000000000ull;
783cab2bb3Spatrick static const uptr kHeapMemBeg = 0x7b0000000000ull;
793cab2bb3Spatrick static const uptr kHeapMemEnd = 0x7c0000000000ull;
803cab2bb3Spatrick static const uptr kLoAppMemBeg = 0x000000001000ull;
813cab2bb3Spatrick static const uptr kLoAppMemEnd = 0x008000000000ull;
823cab2bb3Spatrick static const uptr kMidAppMemBeg = 0x550000000000ull;
833cab2bb3Spatrick static const uptr kMidAppMemEnd = 0x568000000000ull;
843cab2bb3Spatrick static const uptr kHiAppMemBeg = 0x7e8000000000ull;
853cab2bb3Spatrick static const uptr kHiAppMemEnd = 0x800000000000ull;
86*810390e3Srobert static const uptr kShadowMsk = 0x780000000000ull;
87*810390e3Srobert static const uptr kShadowXor = 0x040000000000ull;
88*810390e3Srobert static const uptr kShadowAdd = 0x000000000000ull;
893cab2bb3Spatrick static const uptr kVdsoBeg = 0xf000000000000000ull;
903cab2bb3Spatrick };
913cab2bb3Spatrick
923cab2bb3Spatrick /*
933cab2bb3Spatrick C/C++ on linux/mips64 (40-bit VMA)
943cab2bb3Spatrick 0000 0000 00 - 0100 0000 00: - (4 GB)
953cab2bb3Spatrick 0100 0000 00 - 0200 0000 00: main binary (4 GB)
96*810390e3Srobert 0200 0000 00 - 1200 0000 00: - (64 GB)
97*810390e3Srobert 1200 0000 00 - 2200 0000 00: shadow (64 GB)
98*810390e3Srobert 2200 0000 00 - 4000 0000 00: - (120 GB)
993cab2bb3Spatrick 4000 0000 00 - 5000 0000 00: metainfo (memory blocks and sync objects) (64 GB)
1003cab2bb3Spatrick 5000 0000 00 - aa00 0000 00: - (360 GB)
1013cab2bb3Spatrick aa00 0000 00 - ab00 0000 00: main binary (PIE) (4 GB)
102*810390e3Srobert ab00 0000 00 - fe00 0000 00: - (332 GB)
1033cab2bb3Spatrick fe00 0000 00 - ff00 0000 00: heap (4 GB)
1043cab2bb3Spatrick ff00 0000 00 - ff80 0000 00: - (2 GB)
1053cab2bb3Spatrick ff80 0000 00 - ffff ffff ff: modules and main thread stack (<2 GB)
1063cab2bb3Spatrick */
107*810390e3Srobert struct MappingMips64_40 {
1083cab2bb3Spatrick static const uptr kMetaShadowBeg = 0x4000000000ull;
1093cab2bb3Spatrick static const uptr kMetaShadowEnd = 0x5000000000ull;
110*810390e3Srobert static const uptr kShadowBeg = 0x1200000000ull;
111*810390e3Srobert static const uptr kShadowEnd = 0x2200000000ull;
1123cab2bb3Spatrick static const uptr kHeapMemBeg = 0xfe00000000ull;
1133cab2bb3Spatrick static const uptr kHeapMemEnd = 0xff00000000ull;
1143cab2bb3Spatrick static const uptr kLoAppMemBeg = 0x0100000000ull;
1153cab2bb3Spatrick static const uptr kLoAppMemEnd = 0x0200000000ull;
1163cab2bb3Spatrick static const uptr kMidAppMemBeg = 0xaa00000000ull;
1173cab2bb3Spatrick static const uptr kMidAppMemEnd = 0xab00000000ull;
1183cab2bb3Spatrick static const uptr kHiAppMemBeg = 0xff80000000ull;
1193cab2bb3Spatrick static const uptr kHiAppMemEnd = 0xffffffffffull;
120*810390e3Srobert static const uptr kShadowMsk = 0xf800000000ull;
121*810390e3Srobert static const uptr kShadowXor = 0x0800000000ull;
122*810390e3Srobert static const uptr kShadowAdd = 0x0000000000ull;
1233cab2bb3Spatrick static const uptr kVdsoBeg = 0xfffff00000ull;
1243cab2bb3Spatrick };
1253cab2bb3Spatrick
1263cab2bb3Spatrick /*
1273cab2bb3Spatrick C/C++ on Darwin/iOS/ARM64 (36-bit VMA, 64 GB VM)
1283cab2bb3Spatrick 0000 0000 00 - 0100 0000 00: - (4 GB)
1293cab2bb3Spatrick 0100 0000 00 - 0200 0000 00: main binary, modules, thread stacks (4 GB)
1303cab2bb3Spatrick 0200 0000 00 - 0300 0000 00: heap (4 GB)
1313cab2bb3Spatrick 0300 0000 00 - 0400 0000 00: - (4 GB)
132*810390e3Srobert 0400 0000 00 - 0800 0000 00: shadow memory (16 GB)
133*810390e3Srobert 0800 0000 00 - 0d00 0000 00: - (20 GB)
1343cab2bb3Spatrick 0d00 0000 00 - 0e00 0000 00: metainfo (4 GB)
135*810390e3Srobert 0e00 0000 00 - 1000 0000 00: -
1363cab2bb3Spatrick */
137*810390e3Srobert struct MappingAppleAarch64 {
1383cab2bb3Spatrick static const uptr kLoAppMemBeg = 0x0100000000ull;
1393cab2bb3Spatrick static const uptr kLoAppMemEnd = 0x0200000000ull;
1403cab2bb3Spatrick static const uptr kHeapMemBeg = 0x0200000000ull;
1413cab2bb3Spatrick static const uptr kHeapMemEnd = 0x0300000000ull;
1423cab2bb3Spatrick static const uptr kShadowBeg = 0x0400000000ull;
143*810390e3Srobert static const uptr kShadowEnd = 0x0800000000ull;
1443cab2bb3Spatrick static const uptr kMetaShadowBeg = 0x0d00000000ull;
1453cab2bb3Spatrick static const uptr kMetaShadowEnd = 0x0e00000000ull;
1463cab2bb3Spatrick static const uptr kHiAppMemBeg = 0x0fc0000000ull;
1473cab2bb3Spatrick static const uptr kHiAppMemEnd = 0x0fc0000000ull;
148*810390e3Srobert static const uptr kShadowMsk = 0x0ull;
149*810390e3Srobert static const uptr kShadowXor = 0x0ull;
150*810390e3Srobert static const uptr kShadowAdd = 0x0200000000ull;
1513cab2bb3Spatrick static const uptr kVdsoBeg = 0x7000000000000000ull;
152*810390e3Srobert static const uptr kMidAppMemBeg = 0;
153*810390e3Srobert static const uptr kMidAppMemEnd = 0;
1543cab2bb3Spatrick };
1553cab2bb3Spatrick
1563cab2bb3Spatrick /*
1573cab2bb3Spatrick C/C++ on linux/aarch64 (39-bit VMA)
158*810390e3Srobert 0000 0010 00 - 0500 0000 00: main binary (20 GB)
159*810390e3Srobert 0100 0000 00 - 2000 0000 00: -
160*810390e3Srobert 2000 0000 00 - 4000 0000 00: shadow memory (128 GB)
161*810390e3Srobert 4000 0000 00 - 4800 0000 00: metainfo (32 GB)
162*810390e3Srobert 4800 0000 00 - 5500 0000 00: -
163*810390e3Srobert 5500 0000 00 - 5a00 0000 00: main binary (PIE) (20 GB)
164*810390e3Srobert 5600 0000 00 - 7c00 0000 00: -
165*810390e3Srobert 7a00 0000 00 - 7d00 0000 00: heap (12 GB)
166*810390e3Srobert 7d00 0000 00 - 7fff ffff ff: modules and main thread stack (12 GB)
1673cab2bb3Spatrick */
168*810390e3Srobert struct MappingAarch64_39 {
1693cab2bb3Spatrick static const uptr kLoAppMemBeg = 0x0000001000ull;
170*810390e3Srobert static const uptr kLoAppMemEnd = 0x0500000000ull;
171*810390e3Srobert static const uptr kShadowBeg = 0x2000000000ull;
172*810390e3Srobert static const uptr kShadowEnd = 0x4000000000ull;
173*810390e3Srobert static const uptr kMetaShadowBeg = 0x4000000000ull;
174*810390e3Srobert static const uptr kMetaShadowEnd = 0x4800000000ull;
1753cab2bb3Spatrick static const uptr kMidAppMemBeg = 0x5500000000ull;
176*810390e3Srobert static const uptr kMidAppMemEnd = 0x5a00000000ull;
177*810390e3Srobert static const uptr kHeapMemBeg = 0x7a00000000ull;
1783cab2bb3Spatrick static const uptr kHeapMemEnd = 0x7d00000000ull;
179*810390e3Srobert static const uptr kHiAppMemBeg = 0x7d00000000ull;
1803cab2bb3Spatrick static const uptr kHiAppMemEnd = 0x7fffffffffull;
181*810390e3Srobert static const uptr kShadowMsk = 0x7000000000ull;
182*810390e3Srobert static const uptr kShadowXor = 0x1000000000ull;
183*810390e3Srobert static const uptr kShadowAdd = 0x0000000000ull;
1843cab2bb3Spatrick static const uptr kVdsoBeg = 0x7f00000000ull;
1853cab2bb3Spatrick };
1863cab2bb3Spatrick
1873cab2bb3Spatrick /*
1883cab2bb3Spatrick C/C++ on linux/aarch64 (42-bit VMA)
189*810390e3Srobert 00000 0010 00 - 02000 0000 00: main binary (128 GB)
190*810390e3Srobert 02000 0000 00 - 08000 0000 00: -
191*810390e3Srobert 10000 0000 00 - 20000 0000 00: shadow memory (1024 GB)
192*810390e3Srobert 20000 0000 00 - 24000 0000 00: metainfo (256 GB)
193*810390e3Srobert 24000 0000 00 - 2aa00 0000 00: -
194*810390e3Srobert 2aa00 0000 00 - 2c000 0000 00: main binary (PIE) (88 GB)
195*810390e3Srobert 2c000 0000 00 - 3c000 0000 00: -
196*810390e3Srobert 3c000 0000 00 - 3f000 0000 00: heap (192 GB)
197*810390e3Srobert 3f000 0000 00 - 3ffff ffff ff: modules and main thread stack (64 GB)
1983cab2bb3Spatrick */
199*810390e3Srobert struct MappingAarch64_42 {
2003cab2bb3Spatrick static const uptr kLoAppMemBeg = 0x00000001000ull;
201*810390e3Srobert static const uptr kLoAppMemEnd = 0x02000000000ull;
2023cab2bb3Spatrick static const uptr kShadowBeg = 0x10000000000ull;
2033cab2bb3Spatrick static const uptr kShadowEnd = 0x20000000000ull;
204*810390e3Srobert static const uptr kMetaShadowBeg = 0x20000000000ull;
205*810390e3Srobert static const uptr kMetaShadowEnd = 0x24000000000ull;
2063cab2bb3Spatrick static const uptr kMidAppMemBeg = 0x2aa00000000ull;
207*810390e3Srobert static const uptr kMidAppMemEnd = 0x2c000000000ull;
208*810390e3Srobert static const uptr kHeapMemBeg = 0x3c000000000ull;
2093cab2bb3Spatrick static const uptr kHeapMemEnd = 0x3f000000000ull;
2103cab2bb3Spatrick static const uptr kHiAppMemBeg = 0x3f000000000ull;
2113cab2bb3Spatrick static const uptr kHiAppMemEnd = 0x3ffffffffffull;
212*810390e3Srobert static const uptr kShadowMsk = 0x38000000000ull;
213*810390e3Srobert static const uptr kShadowXor = 0x08000000000ull;
214*810390e3Srobert static const uptr kShadowAdd = 0x00000000000ull;
2153cab2bb3Spatrick static const uptr kVdsoBeg = 0x37f00000000ull;
2163cab2bb3Spatrick };
2173cab2bb3Spatrick
218*810390e3Srobert /*
219*810390e3Srobert C/C++ on linux/aarch64 (48-bit VMA)
220*810390e3Srobert 0000 0000 1000 - 0a00 0000 0000: main binary (10240 GB)
221*810390e3Srobert 0a00 0000 1000 - 1554 0000 0000: -
222*810390e3Srobert 1554 0000 1000 - 5400 0000 0000: shadow memory (64176 GB)
223*810390e3Srobert 5400 0000 1000 - 8000 0000 0000: -
224*810390e3Srobert 8000 0000 1000 - 0a00 0000 0000: metainfo (32768 GB)
225*810390e3Srobert a000 0000 1000 - aaaa 0000 0000: -
226*810390e3Srobert aaaa 0000 1000 - ac00 0000 0000: main binary (PIE) (1368 GB)
227*810390e3Srobert ac00 0000 1000 - fc00 0000 0000: -
228*810390e3Srobert fc00 0000 1000 - ffff ffff ffff: modules and main thread stack (4096 GB)
229*810390e3Srobert
230*810390e3Srobert N.B. the shadow memory region has a strange start address, because it
231*810390e3Srobert contains the shadows for the mid, high and low app regions (in this
232*810390e3Srobert unusual order).
233*810390e3Srobert */
234*810390e3Srobert struct MappingAarch64_48 {
2353cab2bb3Spatrick static const uptr kLoAppMemBeg = 0x0000000001000ull;
236*810390e3Srobert static const uptr kLoAppMemEnd = 0x00a0000000000ull;
237*810390e3Srobert static const uptr kShadowBeg = 0x0155400000000ull;
238*810390e3Srobert static const uptr kShadowEnd = 0x0540000000000ull;
239*810390e3Srobert static const uptr kMetaShadowBeg = 0x0800000000000ull;
240*810390e3Srobert static const uptr kMetaShadowEnd = 0x0a00000000000ull;
2413cab2bb3Spatrick static const uptr kMidAppMemBeg = 0x0aaaa00000000ull;
242*810390e3Srobert static const uptr kMidAppMemEnd = 0x0ac0000000000ull;
243*810390e3Srobert static const uptr kHiAppMemBeg = 0x0fc0000000000ull;
2443cab2bb3Spatrick static const uptr kHiAppMemEnd = 0x1000000000000ull;
245*810390e3Srobert static const uptr kHeapMemBeg = 0x0fc0000000000ull;
246*810390e3Srobert static const uptr kHeapMemEnd = 0x0fc0000000000ull;
247*810390e3Srobert static const uptr kShadowMsk = 0x0c00000000000ull;
248*810390e3Srobert static const uptr kShadowXor = 0x0200000000000ull;
249*810390e3Srobert static const uptr kShadowAdd = 0x0000000000000ull;
2503cab2bb3Spatrick static const uptr kVdsoBeg = 0xffff000000000ull;
2513cab2bb3Spatrick };
2523cab2bb3Spatrick
253*810390e3Srobert /* C/C++ on linux/loongarch64 (47-bit VMA)
254*810390e3Srobert 0000 0000 4000 - 0080 0000 0000: main binary
255*810390e3Srobert 0080 0000 0000 - 0100 0000 0000: -
256*810390e3Srobert 0100 0000 0000 - 1000 0000 0000: shadow memory
257*810390e3Srobert 1000 0000 0000 - 3000 0000 0000: -
258*810390e3Srobert 3000 0000 0000 - 3400 0000 0000: metainfo
259*810390e3Srobert 3400 0000 0000 - 5555 0000 0000: -
260*810390e3Srobert 5555 0000 0000 - 5556 0000 0000: main binary (PIE)
261*810390e3Srobert 5556 0000 0000 - 7ffe 0000 0000: -
262*810390e3Srobert 7ffe 0000 0000 - 7fff 0000 0000: heap
263*810390e3Srobert 7fff 0000 0000 - 7fff 8000 0000: -
264*810390e3Srobert 7fff 8000 0000 - 8000 0000 0000: modules and main thread stack
265*810390e3Srobert */
266*810390e3Srobert struct MappingLoongArch64_47 {
267*810390e3Srobert static const uptr kMetaShadowBeg = 0x300000000000ull;
268*810390e3Srobert static const uptr kMetaShadowEnd = 0x340000000000ull;
269*810390e3Srobert static const uptr kShadowBeg = 0x010000000000ull;
270*810390e3Srobert static const uptr kShadowEnd = 0x100000000000ull;
271*810390e3Srobert static const uptr kHeapMemBeg = 0x7ffe00000000ull;
272*810390e3Srobert static const uptr kHeapMemEnd = 0x7fff00000000ull;
273*810390e3Srobert static const uptr kLoAppMemBeg = 0x000000004000ull;
274*810390e3Srobert static const uptr kLoAppMemEnd = 0x008000000000ull;
275*810390e3Srobert static const uptr kMidAppMemBeg = 0x555500000000ull;
276*810390e3Srobert static const uptr kMidAppMemEnd = 0x555600000000ull;
277*810390e3Srobert static const uptr kHiAppMemBeg = 0x7fff80000000ull;
278*810390e3Srobert static const uptr kHiAppMemEnd = 0x800000000000ull;
279*810390e3Srobert static const uptr kShadowMsk = 0x780000000000ull;
280*810390e3Srobert static const uptr kShadowXor = 0x040000000000ull;
281*810390e3Srobert static const uptr kShadowAdd = 0x000000000000ull;
282*810390e3Srobert static const uptr kVdsoBeg = 0x7fffffffc000ull;
283*810390e3Srobert };
2843cab2bb3Spatrick
2853cab2bb3Spatrick /*
2863cab2bb3Spatrick C/C++ on linux/powerpc64 (44-bit VMA)
2873cab2bb3Spatrick 0000 0000 0100 - 0001 0000 0000: main binary
2883cab2bb3Spatrick 0001 0000 0000 - 0001 0000 0000: -
2893cab2bb3Spatrick 0001 0000 0000 - 0b00 0000 0000: shadow
2903cab2bb3Spatrick 0b00 0000 0000 - 0b00 0000 0000: -
2913cab2bb3Spatrick 0b00 0000 0000 - 0d00 0000 0000: metainfo (memory blocks and sync objects)
292*810390e3Srobert 0d00 0000 0000 - 0f00 0000 0000: -
2933cab2bb3Spatrick 0f00 0000 0000 - 0f50 0000 0000: heap
2943cab2bb3Spatrick 0f50 0000 0000 - 0f60 0000 0000: -
2953cab2bb3Spatrick 0f60 0000 0000 - 1000 0000 0000: modules and main thread stack
2963cab2bb3Spatrick */
297*810390e3Srobert struct MappingPPC64_44 {
298*810390e3Srobert static const uptr kBroken = kBrokenMapping | kBrokenReverseMapping |
299*810390e3Srobert kBrokenLinearity | kBrokenAliasedMetas;
3003cab2bb3Spatrick static const uptr kMetaShadowBeg = 0x0b0000000000ull;
3013cab2bb3Spatrick static const uptr kMetaShadowEnd = 0x0d0000000000ull;
3023cab2bb3Spatrick static const uptr kShadowBeg = 0x000100000000ull;
3033cab2bb3Spatrick static const uptr kShadowEnd = 0x0b0000000000ull;
3043cab2bb3Spatrick static const uptr kLoAppMemBeg = 0x000000000100ull;
3053cab2bb3Spatrick static const uptr kLoAppMemEnd = 0x000100000000ull;
3063cab2bb3Spatrick static const uptr kHeapMemBeg = 0x0f0000000000ull;
3073cab2bb3Spatrick static const uptr kHeapMemEnd = 0x0f5000000000ull;
3083cab2bb3Spatrick static const uptr kHiAppMemBeg = 0x0f6000000000ull;
3093cab2bb3Spatrick static const uptr kHiAppMemEnd = 0x100000000000ull; // 44 bits
310*810390e3Srobert static const uptr kShadowMsk = 0x0f0000000000ull;
311*810390e3Srobert static const uptr kShadowXor = 0x002100000000ull;
312*810390e3Srobert static const uptr kShadowAdd = 0x000000000000ull;
3133cab2bb3Spatrick static const uptr kVdsoBeg = 0x3c0000000000000ull;
314*810390e3Srobert static const uptr kMidAppMemBeg = 0;
315*810390e3Srobert static const uptr kMidAppMemEnd = 0;
3163cab2bb3Spatrick };
3173cab2bb3Spatrick
3183cab2bb3Spatrick /*
3193cab2bb3Spatrick C/C++ on linux/powerpc64 (46-bit VMA)
3203cab2bb3Spatrick 0000 0000 1000 - 0100 0000 0000: main binary
3213cab2bb3Spatrick 0100 0000 0000 - 0200 0000 0000: -
322*810390e3Srobert 0100 0000 0000 - 0800 0000 0000: shadow
323*810390e3Srobert 0800 0000 0000 - 1000 0000 0000: -
324*810390e3Srobert 1000 0000 0000 - 1200 0000 0000: metainfo (memory blocks and sync objects)
325*810390e3Srobert 1200 0000 0000 - 3d00 0000 0000: -
3263cab2bb3Spatrick 3d00 0000 0000 - 3e00 0000 0000: heap
3273cab2bb3Spatrick 3e00 0000 0000 - 3e80 0000 0000: -
3283cab2bb3Spatrick 3e80 0000 0000 - 4000 0000 0000: modules and main thread stack
3293cab2bb3Spatrick */
330*810390e3Srobert struct MappingPPC64_46 {
3313cab2bb3Spatrick static const uptr kMetaShadowBeg = 0x100000000000ull;
332*810390e3Srobert static const uptr kMetaShadowEnd = 0x120000000000ull;
3333cab2bb3Spatrick static const uptr kShadowBeg = 0x010000000000ull;
334*810390e3Srobert static const uptr kShadowEnd = 0x080000000000ull;
3353cab2bb3Spatrick static const uptr kHeapMemBeg = 0x3d0000000000ull;
3363cab2bb3Spatrick static const uptr kHeapMemEnd = 0x3e0000000000ull;
3373cab2bb3Spatrick static const uptr kLoAppMemBeg = 0x000000001000ull;
3383cab2bb3Spatrick static const uptr kLoAppMemEnd = 0x010000000000ull;
3393cab2bb3Spatrick static const uptr kHiAppMemBeg = 0x3e8000000000ull;
3403cab2bb3Spatrick static const uptr kHiAppMemEnd = 0x400000000000ull; // 46 bits
341*810390e3Srobert static const uptr kShadowMsk = 0x3c0000000000ull;
342*810390e3Srobert static const uptr kShadowXor = 0x020000000000ull;
343*810390e3Srobert static const uptr kShadowAdd = 0x000000000000ull;
3443cab2bb3Spatrick static const uptr kVdsoBeg = 0x7800000000000000ull;
345*810390e3Srobert static const uptr kMidAppMemBeg = 0;
346*810390e3Srobert static const uptr kMidAppMemEnd = 0;
3473cab2bb3Spatrick };
3483cab2bb3Spatrick
3493cab2bb3Spatrick /*
3503cab2bb3Spatrick C/C++ on linux/powerpc64 (47-bit VMA)
3513cab2bb3Spatrick 0000 0000 1000 - 0100 0000 0000: main binary
3523cab2bb3Spatrick 0100 0000 0000 - 0200 0000 0000: -
353*810390e3Srobert 0100 0000 0000 - 0800 0000 0000: shadow
354*810390e3Srobert 0800 0000 0000 - 1000 0000 0000: -
355*810390e3Srobert 1000 0000 0000 - 1200 0000 0000: metainfo (memory blocks and sync objects)
356*810390e3Srobert 1200 0000 0000 - 7d00 0000 0000: -
3573cab2bb3Spatrick 7d00 0000 0000 - 7e00 0000 0000: heap
3583cab2bb3Spatrick 7e00 0000 0000 - 7e80 0000 0000: -
3593cab2bb3Spatrick 7e80 0000 0000 - 8000 0000 0000: modules and main thread stack
3603cab2bb3Spatrick */
361*810390e3Srobert struct MappingPPC64_47 {
3623cab2bb3Spatrick static const uptr kMetaShadowBeg = 0x100000000000ull;
363*810390e3Srobert static const uptr kMetaShadowEnd = 0x120000000000ull;
3643cab2bb3Spatrick static const uptr kShadowBeg = 0x010000000000ull;
365*810390e3Srobert static const uptr kShadowEnd = 0x080000000000ull;
3663cab2bb3Spatrick static const uptr kHeapMemBeg = 0x7d0000000000ull;
3673cab2bb3Spatrick static const uptr kHeapMemEnd = 0x7e0000000000ull;
3683cab2bb3Spatrick static const uptr kLoAppMemBeg = 0x000000001000ull;
3693cab2bb3Spatrick static const uptr kLoAppMemEnd = 0x010000000000ull;
3703cab2bb3Spatrick static const uptr kHiAppMemBeg = 0x7e8000000000ull;
3713cab2bb3Spatrick static const uptr kHiAppMemEnd = 0x800000000000ull; // 47 bits
372*810390e3Srobert static const uptr kShadowMsk = 0x7c0000000000ull;
373*810390e3Srobert static const uptr kShadowXor = 0x020000000000ull;
374*810390e3Srobert static const uptr kShadowAdd = 0x000000000000ull;
3753cab2bb3Spatrick static const uptr kVdsoBeg = 0x7800000000000000ull;
376*810390e3Srobert static const uptr kMidAppMemBeg = 0;
377*810390e3Srobert static const uptr kMidAppMemEnd = 0;
3783cab2bb3Spatrick };
3793cab2bb3Spatrick
380d89ec533Spatrick /*
381d89ec533Spatrick C/C++ on linux/s390x
382d89ec533Spatrick While the kernel provides a 64-bit address space, we have to restrict ourselves
383d89ec533Spatrick to 48 bits due to how e.g. SyncVar::GetId() works.
384d89ec533Spatrick 0000 0000 1000 - 0e00 0000 0000: binary, modules, stacks - 14 TiB
385*810390e3Srobert 0e00 0000 0000 - 2000 0000 0000: -
386*810390e3Srobert 2000 0000 0000 - 4000 0000 0000: shadow - 32TiB (2 * app)
387*810390e3Srobert 4000 0000 0000 - 9000 0000 0000: -
388d89ec533Spatrick 9000 0000 0000 - 9800 0000 0000: metainfo - 8TiB (0.5 * app)
389*810390e3Srobert 9800 0000 0000 - be00 0000 0000: -
390d89ec533Spatrick be00 0000 0000 - c000 0000 0000: heap - 2TiB (max supported by the allocator)
391d89ec533Spatrick */
392*810390e3Srobert struct MappingS390x {
393d89ec533Spatrick static const uptr kMetaShadowBeg = 0x900000000000ull;
394d89ec533Spatrick static const uptr kMetaShadowEnd = 0x980000000000ull;
395*810390e3Srobert static const uptr kShadowBeg = 0x200000000000ull;
396*810390e3Srobert static const uptr kShadowEnd = 0x400000000000ull;
397d89ec533Spatrick static const uptr kHeapMemBeg = 0xbe0000000000ull;
398d89ec533Spatrick static const uptr kHeapMemEnd = 0xc00000000000ull;
399d89ec533Spatrick static const uptr kLoAppMemBeg = 0x000000001000ull;
400d89ec533Spatrick static const uptr kLoAppMemEnd = 0x0e0000000000ull;
401d89ec533Spatrick static const uptr kHiAppMemBeg = 0xc00000004000ull;
402d89ec533Spatrick static const uptr kHiAppMemEnd = 0xc00000004000ull;
403*810390e3Srobert static const uptr kShadowMsk = 0xb00000000000ull;
404*810390e3Srobert static const uptr kShadowXor = 0x100000000000ull;
405*810390e3Srobert static const uptr kShadowAdd = 0x000000000000ull;
406d89ec533Spatrick static const uptr kVdsoBeg = 0xfffffffff000ull;
407*810390e3Srobert static const uptr kMidAppMemBeg = 0;
408*810390e3Srobert static const uptr kMidAppMemEnd = 0;
409d89ec533Spatrick };
4103cab2bb3Spatrick
4113cab2bb3Spatrick /* Go on linux, darwin and freebsd on x86_64
4123cab2bb3Spatrick 0000 0000 1000 - 0000 1000 0000: executable
4133cab2bb3Spatrick 0000 1000 0000 - 00c0 0000 0000: -
4143cab2bb3Spatrick 00c0 0000 0000 - 00e0 0000 0000: heap
4153cab2bb3Spatrick 00e0 0000 0000 - 2000 0000 0000: -
416*810390e3Srobert 2000 0000 0000 - 21c0 0000 0000: shadow
417*810390e3Srobert 21c0 0000 0000 - 3000 0000 0000: -
4183cab2bb3Spatrick 3000 0000 0000 - 4000 0000 0000: metainfo (memory blocks and sync objects)
419*810390e3Srobert 4000 0000 0000 - 8000 0000 0000: -
4203cab2bb3Spatrick */
4213cab2bb3Spatrick
422*810390e3Srobert struct MappingGo48 {
4233cab2bb3Spatrick static const uptr kMetaShadowBeg = 0x300000000000ull;
4243cab2bb3Spatrick static const uptr kMetaShadowEnd = 0x400000000000ull;
4253cab2bb3Spatrick static const uptr kShadowBeg = 0x200000000000ull;
426*810390e3Srobert static const uptr kShadowEnd = 0x21c000000000ull;
427*810390e3Srobert static const uptr kLoAppMemBeg = 0x000000001000ull;
428*810390e3Srobert static const uptr kLoAppMemEnd = 0x00e000000000ull;
429*810390e3Srobert static const uptr kMidAppMemBeg = 0;
430*810390e3Srobert static const uptr kMidAppMemEnd = 0;
431*810390e3Srobert static const uptr kHiAppMemBeg = 0;
432*810390e3Srobert static const uptr kHiAppMemEnd = 0;
433*810390e3Srobert static const uptr kHeapMemBeg = 0;
434*810390e3Srobert static const uptr kHeapMemEnd = 0;
435*810390e3Srobert static const uptr kVdsoBeg = 0;
436*810390e3Srobert static const uptr kShadowMsk = 0;
437*810390e3Srobert static const uptr kShadowXor = 0;
438*810390e3Srobert static const uptr kShadowAdd = 0x200000000000ull;
4393cab2bb3Spatrick };
4403cab2bb3Spatrick
4413cab2bb3Spatrick /* Go on windows
4423cab2bb3Spatrick 0000 0000 1000 - 0000 1000 0000: executable
4433cab2bb3Spatrick 0000 1000 0000 - 00f8 0000 0000: -
4443cab2bb3Spatrick 00c0 0000 0000 - 00e0 0000 0000: heap
4453cab2bb3Spatrick 00e0 0000 0000 - 0100 0000 0000: -
446*810390e3Srobert 0100 0000 0000 - 0300 0000 0000: shadow
447*810390e3Srobert 0300 0000 0000 - 0700 0000 0000: -
448*810390e3Srobert 0700 0000 0000 - 0770 0000 0000: metainfo (memory blocks and sync objects)
4493cab2bb3Spatrick 07d0 0000 0000 - 8000 0000 0000: -
450*810390e3Srobert PIE binaries currently not supported, but it should be theoretically possible.
4513cab2bb3Spatrick */
4523cab2bb3Spatrick
453*810390e3Srobert struct MappingGoWindows {
454*810390e3Srobert static const uptr kMetaShadowBeg = 0x070000000000ull;
455*810390e3Srobert static const uptr kMetaShadowEnd = 0x077000000000ull;
4563cab2bb3Spatrick static const uptr kShadowBeg = 0x010000000000ull;
457*810390e3Srobert static const uptr kShadowEnd = 0x030000000000ull;
458*810390e3Srobert static const uptr kLoAppMemBeg = 0x000000001000ull;
459*810390e3Srobert static const uptr kLoAppMemEnd = 0x00e000000000ull;
460*810390e3Srobert static const uptr kMidAppMemBeg = 0;
461*810390e3Srobert static const uptr kMidAppMemEnd = 0;
462*810390e3Srobert static const uptr kHiAppMemBeg = 0;
463*810390e3Srobert static const uptr kHiAppMemEnd = 0;
464*810390e3Srobert static const uptr kHeapMemBeg = 0;
465*810390e3Srobert static const uptr kHeapMemEnd = 0;
466*810390e3Srobert static const uptr kVdsoBeg = 0;
467*810390e3Srobert static const uptr kShadowMsk = 0;
468*810390e3Srobert static const uptr kShadowXor = 0;
469*810390e3Srobert static const uptr kShadowAdd = 0x010000000000ull;
4703cab2bb3Spatrick };
4713cab2bb3Spatrick
4723cab2bb3Spatrick /* Go on linux/powerpc64 (46-bit VMA)
4733cab2bb3Spatrick 0000 0000 1000 - 0000 1000 0000: executable
4743cab2bb3Spatrick 0000 1000 0000 - 00c0 0000 0000: -
4753cab2bb3Spatrick 00c0 0000 0000 - 00e0 0000 0000: heap
4763cab2bb3Spatrick 00e0 0000 0000 - 2000 0000 0000: -
477*810390e3Srobert 2000 0000 0000 - 21c0 0000 0000: shadow
478*810390e3Srobert 21c0 0000 0000 - 2400 0000 0000: -
479*810390e3Srobert 2400 0000 0000 - 2470 0000 0000: metainfo (memory blocks and sync objects)
480*810390e3Srobert 2470 0000 0000 - 4000 0000 0000: -
4813cab2bb3Spatrick */
4823cab2bb3Spatrick
483*810390e3Srobert struct MappingGoPPC64_46 {
4843cab2bb3Spatrick static const uptr kMetaShadowBeg = 0x240000000000ull;
485*810390e3Srobert static const uptr kMetaShadowEnd = 0x247000000000ull;
4863cab2bb3Spatrick static const uptr kShadowBeg = 0x200000000000ull;
487*810390e3Srobert static const uptr kShadowEnd = 0x21c000000000ull;
488*810390e3Srobert static const uptr kLoAppMemBeg = 0x000000001000ull;
489*810390e3Srobert static const uptr kLoAppMemEnd = 0x00e000000000ull;
490*810390e3Srobert static const uptr kMidAppMemBeg = 0;
491*810390e3Srobert static const uptr kMidAppMemEnd = 0;
492*810390e3Srobert static const uptr kHiAppMemBeg = 0;
493*810390e3Srobert static const uptr kHiAppMemEnd = 0;
494*810390e3Srobert static const uptr kHeapMemBeg = 0;
495*810390e3Srobert static const uptr kHeapMemEnd = 0;
496*810390e3Srobert static const uptr kVdsoBeg = 0;
497*810390e3Srobert static const uptr kShadowMsk = 0;
498*810390e3Srobert static const uptr kShadowXor = 0;
499*810390e3Srobert static const uptr kShadowAdd = 0x200000000000ull;
5003cab2bb3Spatrick };
5013cab2bb3Spatrick
5023cab2bb3Spatrick /* Go on linux/powerpc64 (47-bit VMA)
5033cab2bb3Spatrick 0000 0000 1000 - 0000 1000 0000: executable
5043cab2bb3Spatrick 0000 1000 0000 - 00c0 0000 0000: -
5053cab2bb3Spatrick 00c0 0000 0000 - 00e0 0000 0000: heap
5063cab2bb3Spatrick 00e0 0000 0000 - 2000 0000 0000: -
507*810390e3Srobert 2000 0000 0000 - 2800 0000 0000: shadow
508*810390e3Srobert 2800 0000 0000 - 3000 0000 0000: -
509*810390e3Srobert 3000 0000 0000 - 3200 0000 0000: metainfo (memory blocks and sync objects)
510*810390e3Srobert 3200 0000 0000 - 8000 0000 0000: -
5113cab2bb3Spatrick */
5123cab2bb3Spatrick
513*810390e3Srobert struct MappingGoPPC64_47 {
5143cab2bb3Spatrick static const uptr kMetaShadowBeg = 0x300000000000ull;
515*810390e3Srobert static const uptr kMetaShadowEnd = 0x320000000000ull;
5163cab2bb3Spatrick static const uptr kShadowBeg = 0x200000000000ull;
517*810390e3Srobert static const uptr kShadowEnd = 0x280000000000ull;
518*810390e3Srobert static const uptr kLoAppMemBeg = 0x000000001000ull;
519*810390e3Srobert static const uptr kLoAppMemEnd = 0x00e000000000ull;
520*810390e3Srobert static const uptr kMidAppMemBeg = 0;
521*810390e3Srobert static const uptr kMidAppMemEnd = 0;
522*810390e3Srobert static const uptr kHiAppMemBeg = 0;
523*810390e3Srobert static const uptr kHiAppMemEnd = 0;
524*810390e3Srobert static const uptr kHeapMemBeg = 0;
525*810390e3Srobert static const uptr kHeapMemEnd = 0;
526*810390e3Srobert static const uptr kVdsoBeg = 0;
527*810390e3Srobert static const uptr kShadowMsk = 0;
528*810390e3Srobert static const uptr kShadowXor = 0;
529*810390e3Srobert static const uptr kShadowAdd = 0x200000000000ull;
5303cab2bb3Spatrick };
5313cab2bb3Spatrick
532d89ec533Spatrick /* Go on linux/aarch64 (48-bit VMA) and darwin/aarch64 (47-bit VMA)
5333cab2bb3Spatrick 0000 0000 1000 - 0000 1000 0000: executable
5343cab2bb3Spatrick 0000 1000 0000 - 00c0 0000 0000: -
5353cab2bb3Spatrick 00c0 0000 0000 - 00e0 0000 0000: heap
5363cab2bb3Spatrick 00e0 0000 0000 - 2000 0000 0000: -
537*810390e3Srobert 2000 0000 0000 - 2800 0000 0000: shadow
538*810390e3Srobert 2800 0000 0000 - 3000 0000 0000: -
539*810390e3Srobert 3000 0000 0000 - 3200 0000 0000: metainfo (memory blocks and sync objects)
540*810390e3Srobert 3200 0000 0000 - 8000 0000 0000: -
5413cab2bb3Spatrick */
542*810390e3Srobert struct MappingGoAarch64 {
5433cab2bb3Spatrick static const uptr kMetaShadowBeg = 0x300000000000ull;
544*810390e3Srobert static const uptr kMetaShadowEnd = 0x320000000000ull;
5453cab2bb3Spatrick static const uptr kShadowBeg = 0x200000000000ull;
546*810390e3Srobert static const uptr kShadowEnd = 0x280000000000ull;
547*810390e3Srobert static const uptr kLoAppMemBeg = 0x000000001000ull;
548*810390e3Srobert static const uptr kLoAppMemEnd = 0x00e000000000ull;
549*810390e3Srobert static const uptr kMidAppMemBeg = 0;
550*810390e3Srobert static const uptr kMidAppMemEnd = 0;
551*810390e3Srobert static const uptr kHiAppMemBeg = 0;
552*810390e3Srobert static const uptr kHiAppMemEnd = 0;
553*810390e3Srobert static const uptr kHeapMemBeg = 0;
554*810390e3Srobert static const uptr kHeapMemEnd = 0;
555*810390e3Srobert static const uptr kVdsoBeg = 0;
556*810390e3Srobert static const uptr kShadowMsk = 0;
557*810390e3Srobert static const uptr kShadowXor = 0;
558*810390e3Srobert static const uptr kShadowAdd = 0x200000000000ull;
5593cab2bb3Spatrick };
5603cab2bb3Spatrick
561d89ec533Spatrick /*
562d89ec533Spatrick Go on linux/mips64 (47-bit VMA)
563d89ec533Spatrick 0000 0000 1000 - 0000 1000 0000: executable
564d89ec533Spatrick 0000 1000 0000 - 00c0 0000 0000: -
565d89ec533Spatrick 00c0 0000 0000 - 00e0 0000 0000: heap
566d89ec533Spatrick 00e0 0000 0000 - 2000 0000 0000: -
567*810390e3Srobert 2000 0000 0000 - 2800 0000 0000: shadow
568*810390e3Srobert 2800 0000 0000 - 3000 0000 0000: -
569*810390e3Srobert 3000 0000 0000 - 3200 0000 0000: metainfo (memory blocks and sync objects)
570*810390e3Srobert 3200 0000 0000 - 8000 0000 0000: -
571d89ec533Spatrick */
572*810390e3Srobert struct MappingGoMips64_47 {
573d89ec533Spatrick static const uptr kMetaShadowBeg = 0x300000000000ull;
574*810390e3Srobert static const uptr kMetaShadowEnd = 0x320000000000ull;
575d89ec533Spatrick static const uptr kShadowBeg = 0x200000000000ull;
576*810390e3Srobert static const uptr kShadowEnd = 0x280000000000ull;
577*810390e3Srobert static const uptr kLoAppMemBeg = 0x000000001000ull;
578*810390e3Srobert static const uptr kLoAppMemEnd = 0x00e000000000ull;
579*810390e3Srobert static const uptr kMidAppMemBeg = 0;
580*810390e3Srobert static const uptr kMidAppMemEnd = 0;
581*810390e3Srobert static const uptr kHiAppMemBeg = 0;
582*810390e3Srobert static const uptr kHiAppMemEnd = 0;
583*810390e3Srobert static const uptr kHeapMemBeg = 0;
584*810390e3Srobert static const uptr kHeapMemEnd = 0;
585*810390e3Srobert static const uptr kVdsoBeg = 0;
586*810390e3Srobert static const uptr kShadowMsk = 0;
587*810390e3Srobert static const uptr kShadowXor = 0;
588*810390e3Srobert static const uptr kShadowAdd = 0x200000000000ull;
589d89ec533Spatrick };
590d89ec533Spatrick
591d89ec533Spatrick /*
592d89ec533Spatrick Go on linux/s390x
593d89ec533Spatrick 0000 0000 1000 - 1000 0000 0000: executable and heap - 16 TiB
594d89ec533Spatrick 1000 0000 0000 - 4000 0000 0000: -
595*810390e3Srobert 4000 0000 0000 - 6000 0000 0000: shadow - 64TiB (4 * app)
596*810390e3Srobert 6000 0000 0000 - 9000 0000 0000: -
597d89ec533Spatrick 9000 0000 0000 - 9800 0000 0000: metainfo - 8TiB (0.5 * app)
598d89ec533Spatrick */
599*810390e3Srobert struct MappingGoS390x {
600d89ec533Spatrick static const uptr kMetaShadowBeg = 0x900000000000ull;
601d89ec533Spatrick static const uptr kMetaShadowEnd = 0x980000000000ull;
602d89ec533Spatrick static const uptr kShadowBeg = 0x400000000000ull;
603*810390e3Srobert static const uptr kShadowEnd = 0x600000000000ull;
604*810390e3Srobert static const uptr kLoAppMemBeg = 0x000000001000ull;
605*810390e3Srobert static const uptr kLoAppMemEnd = 0x100000000000ull;
606*810390e3Srobert static const uptr kMidAppMemBeg = 0;
607*810390e3Srobert static const uptr kMidAppMemEnd = 0;
608*810390e3Srobert static const uptr kHiAppMemBeg = 0;
609*810390e3Srobert static const uptr kHiAppMemEnd = 0;
610*810390e3Srobert static const uptr kHeapMemBeg = 0;
611*810390e3Srobert static const uptr kHeapMemEnd = 0;
612*810390e3Srobert static const uptr kVdsoBeg = 0;
613*810390e3Srobert static const uptr kShadowMsk = 0;
614*810390e3Srobert static const uptr kShadowXor = 0;
615*810390e3Srobert static const uptr kShadowAdd = 0x400000000000ull;
616d89ec533Spatrick };
617d89ec533Spatrick
6183cab2bb3Spatrick extern uptr vmaSize;
6193cab2bb3Spatrick
620*810390e3Srobert template <typename Func, typename Arg>
SelectMapping(Arg arg)621*810390e3Srobert ALWAYS_INLINE auto SelectMapping(Arg arg) {
622*810390e3Srobert #if SANITIZER_GO
623*810390e3Srobert # if defined(__powerpc64__)
624*810390e3Srobert switch (vmaSize) {
625*810390e3Srobert case 46:
626*810390e3Srobert return Func::template Apply<MappingGoPPC64_46>(arg);
627*810390e3Srobert case 47:
628*810390e3Srobert return Func::template Apply<MappingGoPPC64_47>(arg);
629*810390e3Srobert }
630*810390e3Srobert # elif defined(__mips64)
631*810390e3Srobert return Func::template Apply<MappingGoMips64_47>(arg);
632*810390e3Srobert # elif defined(__s390x__)
633*810390e3Srobert return Func::template Apply<MappingGoS390x>(arg);
634*810390e3Srobert # elif defined(__aarch64__)
635*810390e3Srobert return Func::template Apply<MappingGoAarch64>(arg);
636*810390e3Srobert # elif SANITIZER_WINDOWS
637*810390e3Srobert return Func::template Apply<MappingGoWindows>(arg);
638*810390e3Srobert # else
639*810390e3Srobert return Func::template Apply<MappingGo48>(arg);
640*810390e3Srobert # endif
641*810390e3Srobert #else // SANITIZER_GO
642*810390e3Srobert # if SANITIZER_IOS && !SANITIZER_IOSSIM
643*810390e3Srobert return Func::template Apply<MappingAppleAarch64>(arg);
644*810390e3Srobert # elif defined(__x86_64__) || SANITIZER_APPLE
645*810390e3Srobert return Func::template Apply<Mapping48AddressSpace>(arg);
646*810390e3Srobert # elif defined(__aarch64__)
647*810390e3Srobert switch (vmaSize) {
648*810390e3Srobert case 39:
649*810390e3Srobert return Func::template Apply<MappingAarch64_39>(arg);
650*810390e3Srobert case 42:
651*810390e3Srobert return Func::template Apply<MappingAarch64_42>(arg);
652*810390e3Srobert case 48:
653*810390e3Srobert return Func::template Apply<MappingAarch64_48>(arg);
654*810390e3Srobert }
655*810390e3Srobert # elif SANITIZER_LOONGARCH64
656*810390e3Srobert return Func::template Apply<MappingLoongArch64_47>(arg);
657*810390e3Srobert # elif defined(__powerpc64__)
658*810390e3Srobert switch (vmaSize) {
659*810390e3Srobert case 44:
660*810390e3Srobert return Func::template Apply<MappingPPC64_44>(arg);
661*810390e3Srobert case 46:
662*810390e3Srobert return Func::template Apply<MappingPPC64_46>(arg);
663*810390e3Srobert case 47:
664*810390e3Srobert return Func::template Apply<MappingPPC64_47>(arg);
665*810390e3Srobert }
666*810390e3Srobert # elif defined(__mips64)
667*810390e3Srobert return Func::template Apply<MappingMips64_40>(arg);
668*810390e3Srobert # elif defined(__s390x__)
669*810390e3Srobert return Func::template Apply<MappingS390x>(arg);
670*810390e3Srobert # else
671*810390e3Srobert # error "unsupported platform"
672*810390e3Srobert # endif
673*810390e3Srobert #endif
674*810390e3Srobert Die();
675*810390e3Srobert }
676*810390e3Srobert
677*810390e3Srobert template <typename Func>
ForEachMapping()678*810390e3Srobert void ForEachMapping() {
679*810390e3Srobert Func::template Apply<Mapping48AddressSpace>();
680*810390e3Srobert Func::template Apply<MappingMips64_40>();
681*810390e3Srobert Func::template Apply<MappingAppleAarch64>();
682*810390e3Srobert Func::template Apply<MappingAarch64_39>();
683*810390e3Srobert Func::template Apply<MappingAarch64_42>();
684*810390e3Srobert Func::template Apply<MappingAarch64_48>();
685*810390e3Srobert Func::template Apply<MappingLoongArch64_47>();
686*810390e3Srobert Func::template Apply<MappingPPC64_44>();
687*810390e3Srobert Func::template Apply<MappingPPC64_46>();
688*810390e3Srobert Func::template Apply<MappingPPC64_47>();
689*810390e3Srobert Func::template Apply<MappingS390x>();
690*810390e3Srobert Func::template Apply<MappingGo48>();
691*810390e3Srobert Func::template Apply<MappingGoWindows>();
692*810390e3Srobert Func::template Apply<MappingGoPPC64_46>();
693*810390e3Srobert Func::template Apply<MappingGoPPC64_47>();
694*810390e3Srobert Func::template Apply<MappingGoAarch64>();
695*810390e3Srobert Func::template Apply<MappingGoMips64_47>();
696*810390e3Srobert Func::template Apply<MappingGoS390x>();
697*810390e3Srobert }
6983cab2bb3Spatrick
6993cab2bb3Spatrick enum MappingType {
700*810390e3Srobert kLoAppMemBeg,
701*810390e3Srobert kLoAppMemEnd,
702*810390e3Srobert kHiAppMemBeg,
703*810390e3Srobert kHiAppMemEnd,
704*810390e3Srobert kMidAppMemBeg,
705*810390e3Srobert kMidAppMemEnd,
706*810390e3Srobert kHeapMemBeg,
707*810390e3Srobert kHeapMemEnd,
708*810390e3Srobert kShadowBeg,
709*810390e3Srobert kShadowEnd,
710*810390e3Srobert kMetaShadowBeg,
711*810390e3Srobert kMetaShadowEnd,
712*810390e3Srobert kVdsoBeg,
7133cab2bb3Spatrick };
7143cab2bb3Spatrick
715*810390e3Srobert struct MappingField {
7163cab2bb3Spatrick template <typename Mapping>
ApplyMappingField717*810390e3Srobert static uptr Apply(MappingType type) {
718*810390e3Srobert switch (type) {
719*810390e3Srobert case kLoAppMemBeg:
720*810390e3Srobert return Mapping::kLoAppMemBeg;
721*810390e3Srobert case kLoAppMemEnd:
722*810390e3Srobert return Mapping::kLoAppMemEnd;
723*810390e3Srobert case kMidAppMemBeg:
724*810390e3Srobert return Mapping::kMidAppMemBeg;
725*810390e3Srobert case kMidAppMemEnd:
726*810390e3Srobert return Mapping::kMidAppMemEnd;
727*810390e3Srobert case kHiAppMemBeg:
728*810390e3Srobert return Mapping::kHiAppMemBeg;
729*810390e3Srobert case kHiAppMemEnd:
730*810390e3Srobert return Mapping::kHiAppMemEnd;
731*810390e3Srobert case kHeapMemBeg:
732*810390e3Srobert return Mapping::kHeapMemBeg;
733*810390e3Srobert case kHeapMemEnd:
734*810390e3Srobert return Mapping::kHeapMemEnd;
735*810390e3Srobert case kVdsoBeg:
736*810390e3Srobert return Mapping::kVdsoBeg;
737*810390e3Srobert case kShadowBeg:
738*810390e3Srobert return Mapping::kShadowBeg;
739*810390e3Srobert case kShadowEnd:
740*810390e3Srobert return Mapping::kShadowEnd;
741*810390e3Srobert case kMetaShadowBeg:
742*810390e3Srobert return Mapping::kMetaShadowBeg;
743*810390e3Srobert case kMetaShadowEnd:
744*810390e3Srobert return Mapping::kMetaShadowEnd;
745*810390e3Srobert }
746*810390e3Srobert Die();
747*810390e3Srobert }
748*810390e3Srobert };
749*810390e3Srobert
750*810390e3Srobert ALWAYS_INLINE
LoAppMemBeg(void)751*810390e3Srobert uptr LoAppMemBeg(void) { return SelectMapping<MappingField>(kLoAppMemBeg); }
752*810390e3Srobert ALWAYS_INLINE
LoAppMemEnd(void)753*810390e3Srobert uptr LoAppMemEnd(void) { return SelectMapping<MappingField>(kLoAppMemEnd); }
754*810390e3Srobert
755*810390e3Srobert ALWAYS_INLINE
MidAppMemBeg(void)756*810390e3Srobert uptr MidAppMemBeg(void) { return SelectMapping<MappingField>(kMidAppMemBeg); }
757*810390e3Srobert ALWAYS_INLINE
MidAppMemEnd(void)758*810390e3Srobert uptr MidAppMemEnd(void) { return SelectMapping<MappingField>(kMidAppMemEnd); }
759*810390e3Srobert
760*810390e3Srobert ALWAYS_INLINE
HeapMemBeg(void)761*810390e3Srobert uptr HeapMemBeg(void) { return SelectMapping<MappingField>(kHeapMemBeg); }
762*810390e3Srobert ALWAYS_INLINE
HeapMemEnd(void)763*810390e3Srobert uptr HeapMemEnd(void) { return SelectMapping<MappingField>(kHeapMemEnd); }
764*810390e3Srobert
765*810390e3Srobert ALWAYS_INLINE
HiAppMemBeg(void)766*810390e3Srobert uptr HiAppMemBeg(void) { return SelectMapping<MappingField>(kHiAppMemBeg); }
767*810390e3Srobert ALWAYS_INLINE
HiAppMemEnd(void)768*810390e3Srobert uptr HiAppMemEnd(void) { return SelectMapping<MappingField>(kHiAppMemEnd); }
769*810390e3Srobert
770*810390e3Srobert ALWAYS_INLINE
VdsoBeg(void)771*810390e3Srobert uptr VdsoBeg(void) { return SelectMapping<MappingField>(kVdsoBeg); }
772*810390e3Srobert
773*810390e3Srobert ALWAYS_INLINE
ShadowBeg(void)774*810390e3Srobert uptr ShadowBeg(void) { return SelectMapping<MappingField>(kShadowBeg); }
775*810390e3Srobert ALWAYS_INLINE
ShadowEnd(void)776*810390e3Srobert uptr ShadowEnd(void) { return SelectMapping<MappingField>(kShadowEnd); }
777*810390e3Srobert
778*810390e3Srobert ALWAYS_INLINE
MetaShadowBeg(void)779*810390e3Srobert uptr MetaShadowBeg(void) { return SelectMapping<MappingField>(kMetaShadowBeg); }
780*810390e3Srobert ALWAYS_INLINE
MetaShadowEnd(void)781*810390e3Srobert uptr MetaShadowEnd(void) { return SelectMapping<MappingField>(kMetaShadowEnd); }
782*810390e3Srobert
783*810390e3Srobert struct IsAppMemImpl {
784*810390e3Srobert template <typename Mapping>
ApplyIsAppMemImpl785*810390e3Srobert static bool Apply(uptr mem) {
7863cab2bb3Spatrick return (mem >= Mapping::kHeapMemBeg && mem < Mapping::kHeapMemEnd) ||
7873cab2bb3Spatrick (mem >= Mapping::kMidAppMemBeg && mem < Mapping::kMidAppMemEnd) ||
7883cab2bb3Spatrick (mem >= Mapping::kLoAppMemBeg && mem < Mapping::kLoAppMemEnd) ||
7893cab2bb3Spatrick (mem >= Mapping::kHiAppMemBeg && mem < Mapping::kHiAppMemEnd);
7903cab2bb3Spatrick }
791*810390e3Srobert };
7923cab2bb3Spatrick
7933cab2bb3Spatrick ALWAYS_INLINE
IsAppMem(uptr mem)794*810390e3Srobert bool IsAppMem(uptr mem) { return SelectMapping<IsAppMemImpl>(mem); }
7953cab2bb3Spatrick
796*810390e3Srobert struct IsShadowMemImpl {
7973cab2bb3Spatrick template <typename Mapping>
ApplyIsShadowMemImpl798*810390e3Srobert static bool Apply(uptr mem) {
7993cab2bb3Spatrick return mem >= Mapping::kShadowBeg && mem <= Mapping::kShadowEnd;
8003cab2bb3Spatrick }
801*810390e3Srobert };
8023cab2bb3Spatrick
8033cab2bb3Spatrick ALWAYS_INLINE
IsShadowMem(RawShadow * p)804*810390e3Srobert bool IsShadowMem(RawShadow *p) {
805*810390e3Srobert return SelectMapping<IsShadowMemImpl>(reinterpret_cast<uptr>(p));
8063cab2bb3Spatrick }
8073cab2bb3Spatrick
808*810390e3Srobert struct IsMetaMemImpl {
8093cab2bb3Spatrick template <typename Mapping>
ApplyIsMetaMemImpl810*810390e3Srobert static bool Apply(uptr mem) {
8113cab2bb3Spatrick return mem >= Mapping::kMetaShadowBeg && mem <= Mapping::kMetaShadowEnd;
8123cab2bb3Spatrick }
813*810390e3Srobert };
8143cab2bb3Spatrick
8153cab2bb3Spatrick ALWAYS_INLINE
IsMetaMem(const u32 * p)816*810390e3Srobert bool IsMetaMem(const u32 *p) {
817*810390e3Srobert return SelectMapping<IsMetaMemImpl>(reinterpret_cast<uptr>(p));
8183cab2bb3Spatrick }
8193cab2bb3Spatrick
820*810390e3Srobert struct MemToShadowImpl {
8213cab2bb3Spatrick template <typename Mapping>
ApplyMemToShadowImpl822*810390e3Srobert static uptr Apply(uptr x) {
823*810390e3Srobert DCHECK(IsAppMemImpl::Apply<Mapping>(x));
824*810390e3Srobert return (((x) & ~(Mapping::kShadowMsk | (kShadowCell - 1))) ^
825*810390e3Srobert Mapping::kShadowXor) *
826*810390e3Srobert kShadowMultiplier +
827*810390e3Srobert Mapping::kShadowAdd;
8283cab2bb3Spatrick }
829*810390e3Srobert };
8303cab2bb3Spatrick
8313cab2bb3Spatrick ALWAYS_INLINE
MemToShadow(uptr x)832*810390e3Srobert RawShadow *MemToShadow(uptr x) {
833*810390e3Srobert return reinterpret_cast<RawShadow *>(SelectMapping<MemToShadowImpl>(x));
8343cab2bb3Spatrick }
8353cab2bb3Spatrick
836*810390e3Srobert struct MemToMetaImpl {
8373cab2bb3Spatrick template <typename Mapping>
ApplyMemToMetaImpl838*810390e3Srobert static u32 *Apply(uptr x) {
839*810390e3Srobert DCHECK(IsAppMemImpl::Apply<Mapping>(x));
840*810390e3Srobert return (u32 *)(((((x) & ~(Mapping::kShadowMsk | (kMetaShadowCell - 1)))) /
841*810390e3Srobert kMetaShadowCell * kMetaShadowSize) |
842*810390e3Srobert Mapping::kMetaShadowBeg);
8433cab2bb3Spatrick }
844*810390e3Srobert };
8453cab2bb3Spatrick
8463cab2bb3Spatrick ALWAYS_INLINE
MemToMeta(uptr x)847*810390e3Srobert u32 *MemToMeta(uptr x) { return SelectMapping<MemToMetaImpl>(x); }
8483cab2bb3Spatrick
849*810390e3Srobert struct ShadowToMemImpl {
8503cab2bb3Spatrick template <typename Mapping>
ApplyShadowToMemImpl851*810390e3Srobert static uptr Apply(uptr sp) {
852*810390e3Srobert if (!IsShadowMemImpl::Apply<Mapping>(sp))
853*810390e3Srobert return 0;
854*810390e3Srobert // The shadow mapping is non-linear and we've lost some bits, so we don't
855*810390e3Srobert // have an easy way to restore the original app address. But the mapping is
856*810390e3Srobert // a bijection, so we try to restore the address as belonging to
857*810390e3Srobert // low/mid/high range consecutively and see if shadow->app->shadow mapping
858*810390e3Srobert // gives us the same address.
859*810390e3Srobert uptr p =
860*810390e3Srobert ((sp - Mapping::kShadowAdd) / kShadowMultiplier) ^ Mapping::kShadowXor;
8613cab2bb3Spatrick if (p >= Mapping::kLoAppMemBeg && p < Mapping::kLoAppMemEnd &&
862*810390e3Srobert MemToShadowImpl::Apply<Mapping>(p) == sp)
8633cab2bb3Spatrick return p;
864*810390e3Srobert if (Mapping::kMidAppMemBeg) {
865*810390e3Srobert uptr p_mid = p + (Mapping::kMidAppMemBeg & Mapping::kShadowMsk);
866*810390e3Srobert if (p_mid >= Mapping::kMidAppMemBeg && p_mid < Mapping::kMidAppMemEnd &&
867*810390e3Srobert MemToShadowImpl::Apply<Mapping>(p_mid) == sp)
868*810390e3Srobert return p_mid;
8693cab2bb3Spatrick }
870*810390e3Srobert return p | Mapping::kShadowMsk;
871*810390e3Srobert }
872*810390e3Srobert };
8733cab2bb3Spatrick
8743cab2bb3Spatrick ALWAYS_INLINE
ShadowToMem(RawShadow * s)875*810390e3Srobert uptr ShadowToMem(RawShadow *s) {
876*810390e3Srobert return SelectMapping<ShadowToMemImpl>(reinterpret_cast<uptr>(s));
8773cab2bb3Spatrick }
8783cab2bb3Spatrick
879*810390e3Srobert // Compresses addr to kCompressedAddrBits stored in least significant bits.
CompressAddr(uptr addr)880*810390e3Srobert ALWAYS_INLINE uptr CompressAddr(uptr addr) {
881*810390e3Srobert return addr & ((1ull << kCompressedAddrBits) - 1);
882*810390e3Srobert }
8833cab2bb3Spatrick
884*810390e3Srobert struct RestoreAddrImpl {
885*810390e3Srobert typedef uptr Result;
8863cab2bb3Spatrick template <typename Mapping>
ApplyRestoreAddrImpl887*810390e3Srobert static Result Apply(uptr addr) {
888*810390e3Srobert // To restore the address we go over all app memory ranges and check if top
889*810390e3Srobert // 3 bits of the compressed addr match that of the app range. If yes, we
890*810390e3Srobert // assume that the compressed address come from that range and restore the
891*810390e3Srobert // missing top bits to match the app range address.
892*810390e3Srobert const uptr ranges[] = {
893*810390e3Srobert Mapping::kLoAppMemBeg, Mapping::kLoAppMemEnd, Mapping::kMidAppMemBeg,
894*810390e3Srobert Mapping::kMidAppMemEnd, Mapping::kHiAppMemBeg, Mapping::kHiAppMemEnd,
895*810390e3Srobert Mapping::kHeapMemBeg, Mapping::kHeapMemEnd,
896*810390e3Srobert };
897*810390e3Srobert const uptr indicator = 0x0e0000000000ull;
898*810390e3Srobert const uptr ind_lsb = 1ull << LeastSignificantSetBitIndex(indicator);
899*810390e3Srobert for (uptr i = 0; i < ARRAY_SIZE(ranges); i += 2) {
900*810390e3Srobert uptr beg = ranges[i];
901*810390e3Srobert uptr end = ranges[i + 1];
902*810390e3Srobert if (beg == end)
903*810390e3Srobert continue;
904*810390e3Srobert for (uptr p = beg; p < end; p = RoundDown(p + ind_lsb, ind_lsb)) {
905*810390e3Srobert if ((addr & indicator) == (p & indicator))
906*810390e3Srobert return addr | (p & ~(ind_lsb - 1));
9073cab2bb3Spatrick }
908*810390e3Srobert }
909*810390e3Srobert Printf("ThreadSanitizer: failed to restore address 0x%zx\n", addr);
910*810390e3Srobert Die();
911*810390e3Srobert }
912*810390e3Srobert };
9133cab2bb3Spatrick
914*810390e3Srobert // Restores compressed addr from kCompressedAddrBits to full representation.
915*810390e3Srobert // This is called only during reporting and is not performance-critical.
RestoreAddr(uptr addr)916*810390e3Srobert inline uptr RestoreAddr(uptr addr) {
917*810390e3Srobert return SelectMapping<RestoreAddrImpl>(addr);
9183cab2bb3Spatrick }
9193cab2bb3Spatrick
9203cab2bb3Spatrick void InitializePlatform();
9213cab2bb3Spatrick void InitializePlatformEarly();
9223cab2bb3Spatrick void CheckAndProtect();
9233cab2bb3Spatrick void InitializeShadowMemoryPlatform();
924*810390e3Srobert void WriteMemoryProfile(char *buf, uptr buf_size, u64 uptime_ns);
9253cab2bb3Spatrick int ExtractResolvFDs(void *state, int *fds, int nfd);
9263cab2bb3Spatrick int ExtractRecvmsgFDs(void *msg, int *fds, int nfd);
9273cab2bb3Spatrick uptr ExtractLongJmpSp(uptr *env);
9283cab2bb3Spatrick void ImitateTlsWrite(ThreadState *thr, uptr tls_addr, uptr tls_size);
9293cab2bb3Spatrick
930d89ec533Spatrick int call_pthread_cancel_with_cleanup(int (*fn)(void *arg),
9313cab2bb3Spatrick void (*cleanup)(void *arg), void *arg);
9323cab2bb3Spatrick
9333cab2bb3Spatrick void DestroyThreadState();
9341f9cb04fSpatrick void PlatformCleanUpThreadState(ThreadState *thr);
9353cab2bb3Spatrick
9363cab2bb3Spatrick } // namespace __tsan
9373cab2bb3Spatrick
9383cab2bb3Spatrick #endif // TSAN_PLATFORM_H
939