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
24namespace __tsan {
25
26enum {
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/*
48C/C++ on linux/x86_64 and freebsd/x86_64
490000 0000 1000 - 0080 0000 0000: main binary and/or MAP_32BIT mappings (512GB)
500040 0000 0000 - 0100 0000 0000: -
510100 0000 0000 - 1000 0000 0000: shadow
521000 0000 0000 - 3000 0000 0000: -
533000 0000 0000 - 4000 0000 0000: metainfo (memory blocks and sync objects)
544000 0000 0000 - 5500 0000 0000: -
555500 0000 0000 - 5680 0000 0000: pie binaries without ASLR or on 4.1+ kernels
565680 0000 0000 - 7d00 0000 0000: -
577b00 0000 0000 - 7c00 0000 0000: heap
587c00 0000 0000 - 7e80 0000 0000: -
597e80 0000 0000 - 8000 0000 0000: modules and main thread stack
60
61C/C++ on netbsd/amd64 can reuse the same mapping:
62 * The address space starts from 0x1000 (option with 0x0) and ends with
63   0x7f7ffffff000.
64 * LoAppMem-kHeapMemEnd can be reused as it is.
65 * No VDSO support.
66 * No MidAppMem region.
67 * No additional HeapMem region.
68 * HiAppMem contains the stack, loader, shared libraries and heap.
69 * Stack on NetBSD/amd64 has prereserved 128MB.
70 * Heap grows downwards (top-down).
71 * ASLR must be disabled per-process or globally.
72*/
73struct Mapping48AddressSpace {
74  static const uptr kMetaShadowBeg = 0x300000000000ull;
75  static const uptr kMetaShadowEnd = 0x340000000000ull;
76  static const uptr kShadowBeg     = 0x010000000000ull;
77  static const uptr kShadowEnd = 0x100000000000ull;
78  static const uptr kHeapMemBeg    = 0x7b0000000000ull;
79  static const uptr kHeapMemEnd    = 0x7c0000000000ull;
80  static const uptr kLoAppMemBeg   = 0x000000001000ull;
81  static const uptr kLoAppMemEnd   = 0x008000000000ull;
82  static const uptr kMidAppMemBeg  = 0x550000000000ull;
83  static const uptr kMidAppMemEnd  = 0x568000000000ull;
84  static const uptr kHiAppMemBeg   = 0x7e8000000000ull;
85  static const uptr kHiAppMemEnd   = 0x800000000000ull;
86  static const uptr kShadowMsk = 0x780000000000ull;
87  static const uptr kShadowXor = 0x040000000000ull;
88  static const uptr kShadowAdd = 0x000000000000ull;
89  static const uptr kVdsoBeg       = 0xf000000000000000ull;
90};
91
92/*
93C/C++ on linux/mips64 (40-bit VMA)
940000 0000 00 - 0100 0000 00: -                                           (4 GB)
950100 0000 00 - 0200 0000 00: main binary                                 (4 GB)
960200 0000 00 - 1200 0000 00: -                                          (64 GB)
971200 0000 00 - 2200 0000 00: shadow                                     (64 GB)
982200 0000 00 - 4000 0000 00: -                                         (120 GB)
994000 0000 00 - 5000 0000 00: metainfo (memory blocks and sync objects)  (64 GB)
1005000 0000 00 - aa00 0000 00: -                                         (360 GB)
101aa00 0000 00 - ab00 0000 00: main binary (PIE)                           (4 GB)
102ab00 0000 00 - fe00 0000 00: -                                         (332 GB)
103fe00 0000 00 - ff00 0000 00: heap                                        (4 GB)
104ff00 0000 00 - ff80 0000 00: -                                           (2 GB)
105ff80 0000 00 - ffff ffff ff: modules and main thread stack              (<2 GB)
106*/
107struct MappingMips64_40 {
108  static const uptr kMetaShadowBeg = 0x4000000000ull;
109  static const uptr kMetaShadowEnd = 0x5000000000ull;
110  static const uptr kShadowBeg = 0x1200000000ull;
111  static const uptr kShadowEnd = 0x2200000000ull;
112  static const uptr kHeapMemBeg    = 0xfe00000000ull;
113  static const uptr kHeapMemEnd    = 0xff00000000ull;
114  static const uptr kLoAppMemBeg   = 0x0100000000ull;
115  static const uptr kLoAppMemEnd   = 0x0200000000ull;
116  static const uptr kMidAppMemBeg  = 0xaa00000000ull;
117  static const uptr kMidAppMemEnd  = 0xab00000000ull;
118  static const uptr kHiAppMemBeg   = 0xff80000000ull;
119  static const uptr kHiAppMemEnd   = 0xffffffffffull;
120  static const uptr kShadowMsk = 0xf800000000ull;
121  static const uptr kShadowXor = 0x0800000000ull;
122  static const uptr kShadowAdd = 0x0000000000ull;
123  static const uptr kVdsoBeg       = 0xfffff00000ull;
124};
125
126/*
127C/C++ on Darwin/iOS/ARM64 (36-bit VMA, 64 GB VM)
1280000 0000 00 - 0100 0000 00: -                                    (4 GB)
1290100 0000 00 - 0200 0000 00: main binary, modules, thread stacks  (4 GB)
1300200 0000 00 - 0300 0000 00: heap                                 (4 GB)
1310300 0000 00 - 0400 0000 00: -                                    (4 GB)
1320400 0000 00 - 0800 0000 00: shadow memory                       (16 GB)
1330800 0000 00 - 0d00 0000 00: -                                   (20 GB)
1340d00 0000 00 - 0e00 0000 00: metainfo                             (4 GB)
1350e00 0000 00 - 1000 0000 00: -
136*/
137struct MappingAppleAarch64 {
138  static const uptr kLoAppMemBeg   = 0x0100000000ull;
139  static const uptr kLoAppMemEnd   = 0x0200000000ull;
140  static const uptr kHeapMemBeg    = 0x0200000000ull;
141  static const uptr kHeapMemEnd    = 0x0300000000ull;
142  static const uptr kShadowBeg     = 0x0400000000ull;
143  static const uptr kShadowEnd = 0x0800000000ull;
144  static const uptr kMetaShadowBeg = 0x0d00000000ull;
145  static const uptr kMetaShadowEnd = 0x0e00000000ull;
146  static const uptr kHiAppMemBeg   = 0x0fc0000000ull;
147  static const uptr kHiAppMemEnd   = 0x0fc0000000ull;
148  static const uptr kShadowMsk = 0x0ull;
149  static const uptr kShadowXor = 0x0ull;
150  static const uptr kShadowAdd = 0x0200000000ull;
151  static const uptr kVdsoBeg       = 0x7000000000000000ull;
152  static const uptr kMidAppMemBeg = 0;
153  static const uptr kMidAppMemEnd = 0;
154};
155
156/*
157C/C++ on linux/aarch64 (39-bit VMA)
1580000 0010 00 - 0500 0000 00: main binary                    (20 GB)
1590100 0000 00 - 2000 0000 00: -
1602000 0000 00 - 4000 0000 00: shadow memory                 (128 GB)
1614000 0000 00 - 4800 0000 00: metainfo                       (32 GB)
1624800 0000 00 - 5500 0000 00: -
1635500 0000 00 - 5a00 0000 00: main binary (PIE)              (20 GB)
1645600 0000 00 - 7c00 0000 00: -
1657a00 0000 00 - 7d00 0000 00: heap                           (12 GB)
1667d00 0000 00 - 7fff ffff ff: modules and main thread stack  (12 GB)
167*/
168struct MappingAarch64_39 {
169  static const uptr kLoAppMemBeg   = 0x0000001000ull;
170  static const uptr kLoAppMemEnd   = 0x0500000000ull;
171  static const uptr kShadowBeg     = 0x2000000000ull;
172  static const uptr kShadowEnd     = 0x4000000000ull;
173  static const uptr kMetaShadowBeg = 0x4000000000ull;
174  static const uptr kMetaShadowEnd = 0x4800000000ull;
175  static const uptr kMidAppMemBeg  = 0x5500000000ull;
176  static const uptr kMidAppMemEnd  = 0x5a00000000ull;
177  static const uptr kHeapMemBeg    = 0x7a00000000ull;
178  static const uptr kHeapMemEnd    = 0x7d00000000ull;
179  static const uptr kHiAppMemBeg   = 0x7d00000000ull;
180  static const uptr kHiAppMemEnd   = 0x7fffffffffull;
181  static const uptr kShadowMsk     = 0x7000000000ull;
182  static const uptr kShadowXor     = 0x1000000000ull;
183  static const uptr kShadowAdd     = 0x0000000000ull;
184  static const uptr kVdsoBeg       = 0x7f00000000ull;
185};
186
187/*
188C/C++ on linux/aarch64 (42-bit VMA)
18900000 0010 00 - 02000 0000 00: main binary                   (128 GB)
19002000 0000 00 - 08000 0000 00: -
19110000 0000 00 - 20000 0000 00: shadow memory                (1024 GB)
19220000 0000 00 - 24000 0000 00: metainfo                      (256 GB)
19324000 0000 00 - 2aa00 0000 00: -
1942aa00 0000 00 - 2c000 0000 00: main binary (PIE)              (88 GB)
1952c000 0000 00 - 3c000 0000 00: -
1963c000 0000 00 - 3f000 0000 00: heap                          (192 GB)
1973f000 0000 00 - 3ffff ffff ff: modules and main thread stack  (64 GB)
198*/
199struct MappingAarch64_42 {
200  static const uptr kLoAppMemBeg   = 0x00000001000ull;
201  static const uptr kLoAppMemEnd   = 0x02000000000ull;
202  static const uptr kShadowBeg     = 0x10000000000ull;
203  static const uptr kShadowEnd     = 0x20000000000ull;
204  static const uptr kMetaShadowBeg = 0x20000000000ull;
205  static const uptr kMetaShadowEnd = 0x24000000000ull;
206  static const uptr kMidAppMemBeg  = 0x2aa00000000ull;
207  static const uptr kMidAppMemEnd  = 0x2c000000000ull;
208  static const uptr kHeapMemBeg    = 0x3c000000000ull;
209  static const uptr kHeapMemEnd    = 0x3f000000000ull;
210  static const uptr kHiAppMemBeg   = 0x3f000000000ull;
211  static const uptr kHiAppMemEnd   = 0x3ffffffffffull;
212  static const uptr kShadowMsk     = 0x38000000000ull;
213  static const uptr kShadowXor     = 0x08000000000ull;
214  static const uptr kShadowAdd     = 0x00000000000ull;
215  static const uptr kVdsoBeg       = 0x37f00000000ull;
216};
217
218/*
219C/C++ on linux/aarch64 (48-bit VMA)
2200000 0000 1000 - 0a00 0000 0000: main binary                   (10240 GB)
2210a00 0000 1000 - 1554 0000 0000: -
2221554 0000 1000 - 5400 0000 0000: shadow memory                 (64176 GB)
2235400 0000 1000 - 8000 0000 0000: -
2248000 0000 1000 - 0a00 0000 0000: metainfo                      (32768 GB)
225a000 0000 1000 - aaaa 0000 0000: -
226aaaa 0000 1000 - ac00 0000 0000: main binary (PIE)              (1368 GB)
227ac00 0000 1000 - fc00 0000 0000: -
228fc00 0000 1000 - ffff ffff ffff: modules and main thread stack  (4096 GB)
229
230N.B. the shadow memory region has a strange start address, because it
231contains the shadows for the mid, high and low app regions (in this
232unusual order).
233*/
234struct MappingAarch64_48 {
235  static const uptr kLoAppMemBeg   = 0x0000000001000ull;
236  static const uptr kLoAppMemEnd   = 0x00a0000000000ull;
237  static const uptr kShadowBeg     = 0x0155400000000ull;
238  static const uptr kShadowEnd     = 0x0540000000000ull;
239  static const uptr kMetaShadowBeg = 0x0800000000000ull;
240  static const uptr kMetaShadowEnd = 0x0a00000000000ull;
241  static const uptr kMidAppMemBeg  = 0x0aaaa00000000ull;
242  static const uptr kMidAppMemEnd  = 0x0ac0000000000ull;
243  static const uptr kHiAppMemBeg   = 0x0fc0000000000ull;
244  static const uptr kHiAppMemEnd   = 0x1000000000000ull;
245  static const uptr kHeapMemBeg    = 0x0fc0000000000ull;
246  static const uptr kHeapMemEnd    = 0x0fc0000000000ull;
247  static const uptr kShadowMsk     = 0x0c00000000000ull;
248  static const uptr kShadowXor     = 0x0200000000000ull;
249  static const uptr kShadowAdd     = 0x0000000000000ull;
250  static const uptr kVdsoBeg       = 0xffff000000000ull;
251};
252
253/* C/C++ on linux/loongarch64 (47-bit VMA)
2540000 0000 4000 - 0080 0000 0000: main binary
2550080 0000 0000 - 0100 0000 0000: -
2560100 0000 0000 - 1000 0000 0000: shadow memory
2571000 0000 0000 - 3000 0000 0000: -
2583000 0000 0000 - 3400 0000 0000: metainfo
2593400 0000 0000 - 5555 0000 0000: -
2605555 0000 0000 - 5556 0000 0000: main binary (PIE)
2615556 0000 0000 - 7ffe 0000 0000: -
2627ffe 0000 0000 - 7fff 0000 0000: heap
2637fff 0000 0000 - 7fff 8000 0000: -
2647fff 8000 0000 - 8000 0000 0000: modules and main thread stack
265*/
266struct MappingLoongArch64_47 {
267  static const uptr kMetaShadowBeg = 0x300000000000ull;
268  static const uptr kMetaShadowEnd = 0x340000000000ull;
269  static const uptr kShadowBeg     = 0x010000000000ull;
270  static const uptr kShadowEnd     = 0x100000000000ull;
271  static const uptr kHeapMemBeg    = 0x7ffe00000000ull;
272  static const uptr kHeapMemEnd    = 0x7fff00000000ull;
273  static const uptr kLoAppMemBeg   = 0x000000004000ull;
274  static const uptr kLoAppMemEnd   = 0x008000000000ull;
275  static const uptr kMidAppMemBeg  = 0x555500000000ull;
276  static const uptr kMidAppMemEnd  = 0x555600000000ull;
277  static const uptr kHiAppMemBeg   = 0x7fff80000000ull;
278  static const uptr kHiAppMemEnd   = 0x800000000000ull;
279  static const uptr kShadowMsk     = 0x780000000000ull;
280  static const uptr kShadowXor     = 0x040000000000ull;
281  static const uptr kShadowAdd     = 0x000000000000ull;
282  static const uptr kVdsoBeg       = 0x7fffffffc000ull;
283};
284
285/*
286C/C++ on linux/powerpc64 (44-bit VMA)
2870000 0000 0100 - 0001 0000 0000: main binary
2880001 0000 0000 - 0001 0000 0000: -
2890001 0000 0000 - 0b00 0000 0000: shadow
2900b00 0000 0000 - 0b00 0000 0000: -
2910b00 0000 0000 - 0d00 0000 0000: metainfo (memory blocks and sync objects)
2920d00 0000 0000 - 0f00 0000 0000: -
2930f00 0000 0000 - 0f50 0000 0000: heap
2940f50 0000 0000 - 0f60 0000 0000: -
2950f60 0000 0000 - 1000 0000 0000: modules and main thread stack
296*/
297struct MappingPPC64_44 {
298  static const uptr kBroken = kBrokenMapping | kBrokenReverseMapping |
299                              kBrokenLinearity | kBrokenAliasedMetas;
300  static const uptr kMetaShadowBeg = 0x0b0000000000ull;
301  static const uptr kMetaShadowEnd = 0x0d0000000000ull;
302  static const uptr kShadowBeg     = 0x000100000000ull;
303  static const uptr kShadowEnd     = 0x0b0000000000ull;
304  static const uptr kLoAppMemBeg   = 0x000000000100ull;
305  static const uptr kLoAppMemEnd   = 0x000100000000ull;
306  static const uptr kHeapMemBeg    = 0x0f0000000000ull;
307  static const uptr kHeapMemEnd    = 0x0f5000000000ull;
308  static const uptr kHiAppMemBeg   = 0x0f6000000000ull;
309  static const uptr kHiAppMemEnd   = 0x100000000000ull; // 44 bits
310  static const uptr kShadowMsk = 0x0f0000000000ull;
311  static const uptr kShadowXor = 0x002100000000ull;
312  static const uptr kShadowAdd = 0x000000000000ull;
313  static const uptr kVdsoBeg       = 0x3c0000000000000ull;
314  static const uptr kMidAppMemBeg = 0;
315  static const uptr kMidAppMemEnd = 0;
316};
317
318/*
319C/C++ on linux/powerpc64 (46-bit VMA)
3200000 0000 1000 - 0100 0000 0000: main binary
3210100 0000 0000 - 0200 0000 0000: -
3220100 0000 0000 - 0800 0000 0000: shadow
3230800 0000 0000 - 1000 0000 0000: -
3241000 0000 0000 - 1200 0000 0000: metainfo (memory blocks and sync objects)
3251200 0000 0000 - 3d00 0000 0000: -
3263d00 0000 0000 - 3e00 0000 0000: heap
3273e00 0000 0000 - 3e80 0000 0000: -
3283e80 0000 0000 - 4000 0000 0000: modules and main thread stack
329*/
330struct MappingPPC64_46 {
331  static const uptr kMetaShadowBeg = 0x100000000000ull;
332  static const uptr kMetaShadowEnd = 0x120000000000ull;
333  static const uptr kShadowBeg     = 0x010000000000ull;
334  static const uptr kShadowEnd = 0x080000000000ull;
335  static const uptr kHeapMemBeg    = 0x3d0000000000ull;
336  static const uptr kHeapMemEnd    = 0x3e0000000000ull;
337  static const uptr kLoAppMemBeg   = 0x000000001000ull;
338  static const uptr kLoAppMemEnd   = 0x010000000000ull;
339  static const uptr kHiAppMemBeg   = 0x3e8000000000ull;
340  static const uptr kHiAppMemEnd   = 0x400000000000ull; // 46 bits
341  static const uptr kShadowMsk = 0x3c0000000000ull;
342  static const uptr kShadowXor = 0x020000000000ull;
343  static const uptr kShadowAdd = 0x000000000000ull;
344  static const uptr kVdsoBeg       = 0x7800000000000000ull;
345  static const uptr kMidAppMemBeg = 0;
346  static const uptr kMidAppMemEnd = 0;
347};
348
349/*
350C/C++ on linux/powerpc64 (47-bit VMA)
3510000 0000 1000 - 0100 0000 0000: main binary
3520100 0000 0000 - 0200 0000 0000: -
3530100 0000 0000 - 0800 0000 0000: shadow
3540800 0000 0000 - 1000 0000 0000: -
3551000 0000 0000 - 1200 0000 0000: metainfo (memory blocks and sync objects)
3561200 0000 0000 - 7d00 0000 0000: -
3577d00 0000 0000 - 7e00 0000 0000: heap
3587e00 0000 0000 - 7e80 0000 0000: -
3597e80 0000 0000 - 8000 0000 0000: modules and main thread stack
360*/
361struct MappingPPC64_47 {
362  static const uptr kMetaShadowBeg = 0x100000000000ull;
363  static const uptr kMetaShadowEnd = 0x120000000000ull;
364  static const uptr kShadowBeg     = 0x010000000000ull;
365  static const uptr kShadowEnd = 0x080000000000ull;
366  static const uptr kHeapMemBeg    = 0x7d0000000000ull;
367  static const uptr kHeapMemEnd    = 0x7e0000000000ull;
368  static const uptr kLoAppMemBeg   = 0x000000001000ull;
369  static const uptr kLoAppMemEnd   = 0x010000000000ull;
370  static const uptr kHiAppMemBeg   = 0x7e8000000000ull;
371  static const uptr kHiAppMemEnd   = 0x800000000000ull; // 47 bits
372  static const uptr kShadowMsk = 0x7c0000000000ull;
373  static const uptr kShadowXor = 0x020000000000ull;
374  static const uptr kShadowAdd = 0x000000000000ull;
375  static const uptr kVdsoBeg       = 0x7800000000000000ull;
376  static const uptr kMidAppMemBeg = 0;
377  static const uptr kMidAppMemEnd = 0;
378};
379
380/*
381C/C++ on linux/s390x
382While the kernel provides a 64-bit address space, we have to restrict ourselves
383to 48 bits due to how e.g. SyncVar::GetId() works.
3840000 0000 1000 - 0e00 0000 0000: binary, modules, stacks - 14 TiB
3850e00 0000 0000 - 2000 0000 0000: -
3862000 0000 0000 - 4000 0000 0000: shadow - 32TiB (2 * app)
3874000 0000 0000 - 9000 0000 0000: -
3889000 0000 0000 - 9800 0000 0000: metainfo - 8TiB (0.5 * app)
3899800 0000 0000 - be00 0000 0000: -
390be00 0000 0000 - c000 0000 0000: heap - 2TiB (max supported by the allocator)
391*/
392struct MappingS390x {
393  static const uptr kMetaShadowBeg = 0x900000000000ull;
394  static const uptr kMetaShadowEnd = 0x980000000000ull;
395  static const uptr kShadowBeg = 0x200000000000ull;
396  static const uptr kShadowEnd = 0x400000000000ull;
397  static const uptr kHeapMemBeg    = 0xbe0000000000ull;
398  static const uptr kHeapMemEnd    = 0xc00000000000ull;
399  static const uptr kLoAppMemBeg   = 0x000000001000ull;
400  static const uptr kLoAppMemEnd   = 0x0e0000000000ull;
401  static const uptr kHiAppMemBeg   = 0xc00000004000ull;
402  static const uptr kHiAppMemEnd   = 0xc00000004000ull;
403  static const uptr kShadowMsk = 0xb00000000000ull;
404  static const uptr kShadowXor = 0x100000000000ull;
405  static const uptr kShadowAdd = 0x000000000000ull;
406  static const uptr kVdsoBeg       = 0xfffffffff000ull;
407  static const uptr kMidAppMemBeg = 0;
408  static const uptr kMidAppMemEnd = 0;
409};
410
411/* Go on linux, darwin and freebsd on x86_64
4120000 0000 1000 - 0000 1000 0000: executable
4130000 1000 0000 - 00c0 0000 0000: -
41400c0 0000 0000 - 00e0 0000 0000: heap
41500e0 0000 0000 - 2000 0000 0000: -
4162000 0000 0000 - 21c0 0000 0000: shadow
41721c0 0000 0000 - 3000 0000 0000: -
4183000 0000 0000 - 4000 0000 0000: metainfo (memory blocks and sync objects)
4194000 0000 0000 - 8000 0000 0000: -
420*/
421
422struct MappingGo48 {
423  static const uptr kMetaShadowBeg = 0x300000000000ull;
424  static const uptr kMetaShadowEnd = 0x400000000000ull;
425  static const uptr kShadowBeg     = 0x200000000000ull;
426  static const uptr kShadowEnd = 0x21c000000000ull;
427  static const uptr kLoAppMemBeg = 0x000000001000ull;
428  static const uptr kLoAppMemEnd = 0x00e000000000ull;
429  static const uptr kMidAppMemBeg = 0;
430  static const uptr kMidAppMemEnd = 0;
431  static const uptr kHiAppMemBeg = 0;
432  static const uptr kHiAppMemEnd = 0;
433  static const uptr kHeapMemBeg = 0;
434  static const uptr kHeapMemEnd = 0;
435  static const uptr kVdsoBeg = 0;
436  static const uptr kShadowMsk = 0;
437  static const uptr kShadowXor = 0;
438  static const uptr kShadowAdd = 0x200000000000ull;
439};
440
441/* Go on windows
4420000 0000 1000 - 0000 1000 0000: executable
4430000 1000 0000 - 00f8 0000 0000: -
44400c0 0000 0000 - 00e0 0000 0000: heap
44500e0 0000 0000 - 0100 0000 0000: -
4460100 0000 0000 - 0300 0000 0000: shadow
4470300 0000 0000 - 0700 0000 0000: -
4480700 0000 0000 - 0770 0000 0000: metainfo (memory blocks and sync objects)
44907d0 0000 0000 - 8000 0000 0000: -
450PIE binaries currently not supported, but it should be theoretically possible.
451*/
452
453struct MappingGoWindows {
454  static const uptr kMetaShadowBeg = 0x070000000000ull;
455  static const uptr kMetaShadowEnd = 0x077000000000ull;
456  static const uptr kShadowBeg     = 0x010000000000ull;
457  static const uptr kShadowEnd = 0x030000000000ull;
458  static const uptr kLoAppMemBeg = 0x000000001000ull;
459  static const uptr kLoAppMemEnd = 0x00e000000000ull;
460  static const uptr kMidAppMemBeg = 0;
461  static const uptr kMidAppMemEnd = 0;
462  static const uptr kHiAppMemBeg = 0;
463  static const uptr kHiAppMemEnd = 0;
464  static const uptr kHeapMemBeg = 0;
465  static const uptr kHeapMemEnd = 0;
466  static const uptr kVdsoBeg = 0;
467  static const uptr kShadowMsk = 0;
468  static const uptr kShadowXor = 0;
469  static const uptr kShadowAdd = 0x010000000000ull;
470};
471
472/* Go on linux/powerpc64 (46-bit VMA)
4730000 0000 1000 - 0000 1000 0000: executable
4740000 1000 0000 - 00c0 0000 0000: -
47500c0 0000 0000 - 00e0 0000 0000: heap
47600e0 0000 0000 - 2000 0000 0000: -
4772000 0000 0000 - 21c0 0000 0000: shadow
47821c0 0000 0000 - 2400 0000 0000: -
4792400 0000 0000 - 2470 0000 0000: metainfo (memory blocks and sync objects)
4802470 0000 0000 - 4000 0000 0000: -
481*/
482
483struct MappingGoPPC64_46 {
484  static const uptr kMetaShadowBeg = 0x240000000000ull;
485  static const uptr kMetaShadowEnd = 0x247000000000ull;
486  static const uptr kShadowBeg     = 0x200000000000ull;
487  static const uptr kShadowEnd = 0x21c000000000ull;
488  static const uptr kLoAppMemBeg = 0x000000001000ull;
489  static const uptr kLoAppMemEnd = 0x00e000000000ull;
490  static const uptr kMidAppMemBeg = 0;
491  static const uptr kMidAppMemEnd = 0;
492  static const uptr kHiAppMemBeg = 0;
493  static const uptr kHiAppMemEnd = 0;
494  static const uptr kHeapMemBeg = 0;
495  static const uptr kHeapMemEnd = 0;
496  static const uptr kVdsoBeg = 0;
497  static const uptr kShadowMsk = 0;
498  static const uptr kShadowXor = 0;
499  static const uptr kShadowAdd = 0x200000000000ull;
500};
501
502/* Go on linux/powerpc64 (47-bit VMA)
5030000 0000 1000 - 0000 1000 0000: executable
5040000 1000 0000 - 00c0 0000 0000: -
50500c0 0000 0000 - 00e0 0000 0000: heap
50600e0 0000 0000 - 2000 0000 0000: -
5072000 0000 0000 - 2800 0000 0000: shadow
5082800 0000 0000 - 3000 0000 0000: -
5093000 0000 0000 - 3200 0000 0000: metainfo (memory blocks and sync objects)
5103200 0000 0000 - 8000 0000 0000: -
511*/
512
513struct MappingGoPPC64_47 {
514  static const uptr kMetaShadowBeg = 0x300000000000ull;
515  static const uptr kMetaShadowEnd = 0x320000000000ull;
516  static const uptr kShadowBeg     = 0x200000000000ull;
517  static const uptr kShadowEnd = 0x280000000000ull;
518  static const uptr kLoAppMemBeg = 0x000000001000ull;
519  static const uptr kLoAppMemEnd = 0x00e000000000ull;
520  static const uptr kMidAppMemBeg = 0;
521  static const uptr kMidAppMemEnd = 0;
522  static const uptr kHiAppMemBeg = 0;
523  static const uptr kHiAppMemEnd = 0;
524  static const uptr kHeapMemBeg = 0;
525  static const uptr kHeapMemEnd = 0;
526  static const uptr kVdsoBeg = 0;
527  static const uptr kShadowMsk = 0;
528  static const uptr kShadowXor = 0;
529  static const uptr kShadowAdd = 0x200000000000ull;
530};
531
532/* Go on linux/aarch64 (48-bit VMA) and darwin/aarch64 (47-bit VMA)
5330000 0000 1000 - 0000 1000 0000: executable
5340000 1000 0000 - 00c0 0000 0000: -
53500c0 0000 0000 - 00e0 0000 0000: heap
53600e0 0000 0000 - 2000 0000 0000: -
5372000 0000 0000 - 2800 0000 0000: shadow
5382800 0000 0000 - 3000 0000 0000: -
5393000 0000 0000 - 3200 0000 0000: metainfo (memory blocks and sync objects)
5403200 0000 0000 - 8000 0000 0000: -
541*/
542struct MappingGoAarch64 {
543  static const uptr kMetaShadowBeg = 0x300000000000ull;
544  static const uptr kMetaShadowEnd = 0x320000000000ull;
545  static const uptr kShadowBeg     = 0x200000000000ull;
546  static const uptr kShadowEnd = 0x280000000000ull;
547  static const uptr kLoAppMemBeg = 0x000000001000ull;
548  static const uptr kLoAppMemEnd = 0x00e000000000ull;
549  static const uptr kMidAppMemBeg = 0;
550  static const uptr kMidAppMemEnd = 0;
551  static const uptr kHiAppMemBeg = 0;
552  static const uptr kHiAppMemEnd = 0;
553  static const uptr kHeapMemBeg = 0;
554  static const uptr kHeapMemEnd = 0;
555  static const uptr kVdsoBeg = 0;
556  static const uptr kShadowMsk = 0;
557  static const uptr kShadowXor = 0;
558  static const uptr kShadowAdd = 0x200000000000ull;
559};
560
561/*
562Go on linux/mips64 (47-bit VMA)
5630000 0000 1000 - 0000 1000 0000: executable
5640000 1000 0000 - 00c0 0000 0000: -
56500c0 0000 0000 - 00e0 0000 0000: heap
56600e0 0000 0000 - 2000 0000 0000: -
5672000 0000 0000 - 2800 0000 0000: shadow
5682800 0000 0000 - 3000 0000 0000: -
5693000 0000 0000 - 3200 0000 0000: metainfo (memory blocks and sync objects)
5703200 0000 0000 - 8000 0000 0000: -
571*/
572struct MappingGoMips64_47 {
573  static const uptr kMetaShadowBeg = 0x300000000000ull;
574  static const uptr kMetaShadowEnd = 0x320000000000ull;
575  static const uptr kShadowBeg = 0x200000000000ull;
576  static const uptr kShadowEnd = 0x280000000000ull;
577  static const uptr kLoAppMemBeg = 0x000000001000ull;
578  static const uptr kLoAppMemEnd = 0x00e000000000ull;
579  static const uptr kMidAppMemBeg = 0;
580  static const uptr kMidAppMemEnd = 0;
581  static const uptr kHiAppMemBeg = 0;
582  static const uptr kHiAppMemEnd = 0;
583  static const uptr kHeapMemBeg = 0;
584  static const uptr kHeapMemEnd = 0;
585  static const uptr kVdsoBeg = 0;
586  static const uptr kShadowMsk = 0;
587  static const uptr kShadowXor = 0;
588  static const uptr kShadowAdd = 0x200000000000ull;
589};
590
591/*
592Go on linux/s390x
5930000 0000 1000 - 1000 0000 0000: executable and heap - 16 TiB
5941000 0000 0000 - 4000 0000 0000: -
5954000 0000 0000 - 6000 0000 0000: shadow - 64TiB (4 * app)
5966000 0000 0000 - 9000 0000 0000: -
5979000 0000 0000 - 9800 0000 0000: metainfo - 8TiB (0.5 * app)
598*/
599struct MappingGoS390x {
600  static const uptr kMetaShadowBeg = 0x900000000000ull;
601  static const uptr kMetaShadowEnd = 0x980000000000ull;
602  static const uptr kShadowBeg     = 0x400000000000ull;
603  static const uptr kShadowEnd = 0x600000000000ull;
604  static const uptr kLoAppMemBeg = 0x000000001000ull;
605  static const uptr kLoAppMemEnd = 0x100000000000ull;
606  static const uptr kMidAppMemBeg = 0;
607  static const uptr kMidAppMemEnd = 0;
608  static const uptr kHiAppMemBeg = 0;
609  static const uptr kHiAppMemEnd = 0;
610  static const uptr kHeapMemBeg = 0;
611  static const uptr kHeapMemEnd = 0;
612  static const uptr kVdsoBeg = 0;
613  static const uptr kShadowMsk = 0;
614  static const uptr kShadowXor = 0;
615  static const uptr kShadowAdd = 0x400000000000ull;
616};
617
618extern uptr vmaSize;
619
620template <typename Func, typename Arg>
621ALWAYS_INLINE auto SelectMapping(Arg arg) {
622#if SANITIZER_GO
623#  if defined(__powerpc64__)
624  switch (vmaSize) {
625    case 46:
626      return Func::template Apply<MappingGoPPC64_46>(arg);
627    case 47:
628      return Func::template Apply<MappingGoPPC64_47>(arg);
629  }
630#  elif defined(__mips64)
631  return Func::template Apply<MappingGoMips64_47>(arg);
632#  elif defined(__s390x__)
633  return Func::template Apply<MappingGoS390x>(arg);
634#  elif defined(__aarch64__)
635  return Func::template Apply<MappingGoAarch64>(arg);
636#  elif SANITIZER_WINDOWS
637  return Func::template Apply<MappingGoWindows>(arg);
638#  else
639  return Func::template Apply<MappingGo48>(arg);
640#  endif
641#else  // SANITIZER_GO
642#  if SANITIZER_IOS && !SANITIZER_IOSSIM
643  return Func::template Apply<MappingAppleAarch64>(arg);
644#  elif defined(__x86_64__) || SANITIZER_APPLE
645  return Func::template Apply<Mapping48AddressSpace>(arg);
646#  elif defined(__aarch64__)
647  switch (vmaSize) {
648    case 39:
649      return Func::template Apply<MappingAarch64_39>(arg);
650    case 42:
651      return Func::template Apply<MappingAarch64_42>(arg);
652    case 48:
653      return Func::template Apply<MappingAarch64_48>(arg);
654  }
655#  elif SANITIZER_LOONGARCH64
656  return Func::template Apply<MappingLoongArch64_47>(arg);
657#  elif defined(__powerpc64__)
658  switch (vmaSize) {
659    case 44:
660      return Func::template Apply<MappingPPC64_44>(arg);
661    case 46:
662      return Func::template Apply<MappingPPC64_46>(arg);
663    case 47:
664      return Func::template Apply<MappingPPC64_47>(arg);
665  }
666#  elif defined(__mips64)
667  return Func::template Apply<MappingMips64_40>(arg);
668#  elif defined(__s390x__)
669  return Func::template Apply<MappingS390x>(arg);
670#  else
671#    error "unsupported platform"
672#  endif
673#endif
674  Die();
675}
676
677template <typename Func>
678void ForEachMapping() {
679  Func::template Apply<Mapping48AddressSpace>();
680  Func::template Apply<MappingMips64_40>();
681  Func::template Apply<MappingAppleAarch64>();
682  Func::template Apply<MappingAarch64_39>();
683  Func::template Apply<MappingAarch64_42>();
684  Func::template Apply<MappingAarch64_48>();
685  Func::template Apply<MappingLoongArch64_47>();
686  Func::template Apply<MappingPPC64_44>();
687  Func::template Apply<MappingPPC64_46>();
688  Func::template Apply<MappingPPC64_47>();
689  Func::template Apply<MappingS390x>();
690  Func::template Apply<MappingGo48>();
691  Func::template Apply<MappingGoWindows>();
692  Func::template Apply<MappingGoPPC64_46>();
693  Func::template Apply<MappingGoPPC64_47>();
694  Func::template Apply<MappingGoAarch64>();
695  Func::template Apply<MappingGoMips64_47>();
696  Func::template Apply<MappingGoS390x>();
697}
698
699enum MappingType {
700  kLoAppMemBeg,
701  kLoAppMemEnd,
702  kHiAppMemBeg,
703  kHiAppMemEnd,
704  kMidAppMemBeg,
705  kMidAppMemEnd,
706  kHeapMemBeg,
707  kHeapMemEnd,
708  kShadowBeg,
709  kShadowEnd,
710  kMetaShadowBeg,
711  kMetaShadowEnd,
712  kVdsoBeg,
713};
714
715struct MappingField {
716  template <typename Mapping>
717  static uptr Apply(MappingType type) {
718    switch (type) {
719      case kLoAppMemBeg:
720        return Mapping::kLoAppMemBeg;
721      case kLoAppMemEnd:
722        return Mapping::kLoAppMemEnd;
723      case kMidAppMemBeg:
724        return Mapping::kMidAppMemBeg;
725      case kMidAppMemEnd:
726        return Mapping::kMidAppMemEnd;
727      case kHiAppMemBeg:
728        return Mapping::kHiAppMemBeg;
729      case kHiAppMemEnd:
730        return Mapping::kHiAppMemEnd;
731      case kHeapMemBeg:
732        return Mapping::kHeapMemBeg;
733      case kHeapMemEnd:
734        return Mapping::kHeapMemEnd;
735      case kVdsoBeg:
736        return Mapping::kVdsoBeg;
737      case kShadowBeg:
738        return Mapping::kShadowBeg;
739      case kShadowEnd:
740        return Mapping::kShadowEnd;
741      case kMetaShadowBeg:
742        return Mapping::kMetaShadowBeg;
743      case kMetaShadowEnd:
744        return Mapping::kMetaShadowEnd;
745    }
746    Die();
747  }
748};
749
750ALWAYS_INLINE
751uptr LoAppMemBeg(void) { return SelectMapping<MappingField>(kLoAppMemBeg); }
752ALWAYS_INLINE
753uptr LoAppMemEnd(void) { return SelectMapping<MappingField>(kLoAppMemEnd); }
754
755ALWAYS_INLINE
756uptr MidAppMemBeg(void) { return SelectMapping<MappingField>(kMidAppMemBeg); }
757ALWAYS_INLINE
758uptr MidAppMemEnd(void) { return SelectMapping<MappingField>(kMidAppMemEnd); }
759
760ALWAYS_INLINE
761uptr HeapMemBeg(void) { return SelectMapping<MappingField>(kHeapMemBeg); }
762ALWAYS_INLINE
763uptr HeapMemEnd(void) { return SelectMapping<MappingField>(kHeapMemEnd); }
764
765ALWAYS_INLINE
766uptr HiAppMemBeg(void) { return SelectMapping<MappingField>(kHiAppMemBeg); }
767ALWAYS_INLINE
768uptr HiAppMemEnd(void) { return SelectMapping<MappingField>(kHiAppMemEnd); }
769
770ALWAYS_INLINE
771uptr VdsoBeg(void) { return SelectMapping<MappingField>(kVdsoBeg); }
772
773ALWAYS_INLINE
774uptr ShadowBeg(void) { return SelectMapping<MappingField>(kShadowBeg); }
775ALWAYS_INLINE
776uptr ShadowEnd(void) { return SelectMapping<MappingField>(kShadowEnd); }
777
778ALWAYS_INLINE
779uptr MetaShadowBeg(void) { return SelectMapping<MappingField>(kMetaShadowBeg); }
780ALWAYS_INLINE
781uptr MetaShadowEnd(void) { return SelectMapping<MappingField>(kMetaShadowEnd); }
782
783struct IsAppMemImpl {
784  template <typename Mapping>
785  static bool Apply(uptr mem) {
786  return (mem >= Mapping::kHeapMemBeg && mem < Mapping::kHeapMemEnd) ||
787         (mem >= Mapping::kMidAppMemBeg && mem < Mapping::kMidAppMemEnd) ||
788         (mem >= Mapping::kLoAppMemBeg && mem < Mapping::kLoAppMemEnd) ||
789         (mem >= Mapping::kHiAppMemBeg && mem < Mapping::kHiAppMemEnd);
790  }
791};
792
793ALWAYS_INLINE
794bool IsAppMem(uptr mem) { return SelectMapping<IsAppMemImpl>(mem); }
795
796struct IsShadowMemImpl {
797  template <typename Mapping>
798  static bool Apply(uptr mem) {
799    return mem >= Mapping::kShadowBeg && mem <= Mapping::kShadowEnd;
800  }
801};
802
803ALWAYS_INLINE
804bool IsShadowMem(RawShadow *p) {
805  return SelectMapping<IsShadowMemImpl>(reinterpret_cast<uptr>(p));
806}
807
808struct IsMetaMemImpl {
809  template <typename Mapping>
810  static bool Apply(uptr mem) {
811    return mem >= Mapping::kMetaShadowBeg && mem <= Mapping::kMetaShadowEnd;
812  }
813};
814
815ALWAYS_INLINE
816bool IsMetaMem(const u32 *p) {
817  return SelectMapping<IsMetaMemImpl>(reinterpret_cast<uptr>(p));
818}
819
820struct MemToShadowImpl {
821  template <typename Mapping>
822  static uptr Apply(uptr x) {
823    DCHECK(IsAppMemImpl::Apply<Mapping>(x));
824    return (((x) & ~(Mapping::kShadowMsk | (kShadowCell - 1))) ^
825            Mapping::kShadowXor) *
826               kShadowMultiplier +
827           Mapping::kShadowAdd;
828  }
829};
830
831ALWAYS_INLINE
832RawShadow *MemToShadow(uptr x) {
833  return reinterpret_cast<RawShadow *>(SelectMapping<MemToShadowImpl>(x));
834}
835
836struct MemToMetaImpl {
837  template <typename Mapping>
838  static u32 *Apply(uptr x) {
839    DCHECK(IsAppMemImpl::Apply<Mapping>(x));
840    return (u32 *)(((((x) & ~(Mapping::kShadowMsk | (kMetaShadowCell - 1)))) /
841                    kMetaShadowCell * kMetaShadowSize) |
842                   Mapping::kMetaShadowBeg);
843  }
844};
845
846ALWAYS_INLINE
847u32 *MemToMeta(uptr x) { return SelectMapping<MemToMetaImpl>(x); }
848
849struct ShadowToMemImpl {
850  template <typename Mapping>
851  static uptr Apply(uptr sp) {
852    if (!IsShadowMemImpl::Apply<Mapping>(sp))
853      return 0;
854    // The shadow mapping is non-linear and we've lost some bits, so we don't
855    // have an easy way to restore the original app address. But the mapping is
856    // a bijection, so we try to restore the address as belonging to
857    // low/mid/high range consecutively and see if shadow->app->shadow mapping
858    // gives us the same address.
859    uptr p =
860        ((sp - Mapping::kShadowAdd) / kShadowMultiplier) ^ Mapping::kShadowXor;
861    if (p >= Mapping::kLoAppMemBeg && p < Mapping::kLoAppMemEnd &&
862        MemToShadowImpl::Apply<Mapping>(p) == sp)
863      return p;
864    if (Mapping::kMidAppMemBeg) {
865      uptr p_mid = p + (Mapping::kMidAppMemBeg & Mapping::kShadowMsk);
866      if (p_mid >= Mapping::kMidAppMemBeg && p_mid < Mapping::kMidAppMemEnd &&
867          MemToShadowImpl::Apply<Mapping>(p_mid) == sp)
868        return p_mid;
869    }
870    return p | Mapping::kShadowMsk;
871  }
872};
873
874ALWAYS_INLINE
875uptr ShadowToMem(RawShadow *s) {
876  return SelectMapping<ShadowToMemImpl>(reinterpret_cast<uptr>(s));
877}
878
879// Compresses addr to kCompressedAddrBits stored in least significant bits.
880ALWAYS_INLINE uptr CompressAddr(uptr addr) {
881  return addr & ((1ull << kCompressedAddrBits) - 1);
882}
883
884struct RestoreAddrImpl {
885  typedef uptr Result;
886  template <typename Mapping>
887  static Result Apply(uptr addr) {
888    // To restore the address we go over all app memory ranges and check if top
889    // 3 bits of the compressed addr match that of the app range. If yes, we
890    // assume that the compressed address come from that range and restore the
891    // missing top bits to match the app range address.
892    const uptr ranges[] = {
893        Mapping::kLoAppMemBeg,  Mapping::kLoAppMemEnd, Mapping::kMidAppMemBeg,
894        Mapping::kMidAppMemEnd, Mapping::kHiAppMemBeg, Mapping::kHiAppMemEnd,
895        Mapping::kHeapMemBeg,   Mapping::kHeapMemEnd,
896    };
897    const uptr indicator = 0x0e0000000000ull;
898    const uptr ind_lsb = 1ull << LeastSignificantSetBitIndex(indicator);
899    for (uptr i = 0; i < ARRAY_SIZE(ranges); i += 2) {
900      uptr beg = ranges[i];
901      uptr end = ranges[i + 1];
902      if (beg == end)
903        continue;
904      for (uptr p = beg; p < end; p = RoundDown(p + ind_lsb, ind_lsb)) {
905        if ((addr & indicator) == (p & indicator))
906          return addr | (p & ~(ind_lsb - 1));
907      }
908    }
909    Printf("ThreadSanitizer: failed to restore address 0x%zx\n", addr);
910    Die();
911  }
912};
913
914// Restores compressed addr from kCompressedAddrBits to full representation.
915// This is called only during reporting and is not performance-critical.
916inline uptr RestoreAddr(uptr addr) {
917  return SelectMapping<RestoreAddrImpl>(addr);
918}
919
920void InitializePlatform();
921void InitializePlatformEarly();
922void CheckAndProtect();
923void InitializeShadowMemoryPlatform();
924void WriteMemoryProfile(char *buf, uptr buf_size, u64 uptime_ns);
925int ExtractResolvFDs(void *state, int *fds, int nfd);
926int ExtractRecvmsgFDs(void *msg, int *fds, int nfd);
927uptr ExtractLongJmpSp(uptr *env);
928void ImitateTlsWrite(ThreadState *thr, uptr tls_addr, uptr tls_size);
929
930int call_pthread_cancel_with_cleanup(int (*fn)(void *arg),
931                                     void (*cleanup)(void *arg), void *arg);
932
933void DestroyThreadState();
934void PlatformCleanUpThreadState(ThreadState *thr);
935
936}  // namespace __tsan
937
938#endif  // TSAN_PLATFORM_H
939