123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881 |
- //===-- tsan_platform.h -----------------------------------------*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // This file is a part of ThreadSanitizer (TSan), a race detector.
- //
- // Platform-specific code.
- //===----------------------------------------------------------------------===//
- #ifndef TSAN_PLATFORM_H
- #define TSAN_PLATFORM_H
- #if !defined(__LP64__) && !defined(_WIN64)
- # error "Only 64-bit is supported"
- #endif
- #include "sanitizer_common/sanitizer_common.h"
- #include "tsan_defs.h"
- namespace __tsan {
- enum {
- // App memory is not mapped onto shadow memory range.
- kBrokenMapping = 1 << 0,
- // Mapping app memory and back does not produce the same address,
- // this can lead to wrong addresses in reports and potentially
- // other bad consequences.
- kBrokenReverseMapping = 1 << 1,
- // Mapping is non-linear for linear user range.
- // This is bad and can lead to unpredictable memory corruptions, etc
- // because range access functions assume linearity.
- kBrokenLinearity = 1 << 2,
- };
- /*
- C/C++ on linux/x86_64 and freebsd/x86_64
- 0000 0000 1000 - 0080 0000 0000: main binary and/or MAP_32BIT mappings (512GB)
- 0040 0000 0000 - 0100 0000 0000: -
- 0100 0000 0000 - 1000 0000 0000: shadow
- 1000 0000 0000 - 3000 0000 0000: -
- 3000 0000 0000 - 4000 0000 0000: metainfo (memory blocks and sync objects)
- 4000 0000 0000 - 5500 0000 0000: -
- 5500 0000 0000 - 5680 0000 0000: pie binaries without ASLR or on 4.1+ kernels
- 5680 0000 0000 - 7d00 0000 0000: -
- 7b00 0000 0000 - 7c00 0000 0000: heap
- 7c00 0000 0000 - 7e80 0000 0000: -
- 7e80 0000 0000 - 8000 0000 0000: modules and main thread stack
- C/C++ on netbsd/amd64 can reuse the same mapping:
- * The address space starts from 0x1000 (option with 0x0) and ends with
- 0x7f7ffffff000.
- * LoAppMem-kHeapMemEnd can be reused as it is.
- * No VDSO support.
- * No MidAppMem region.
- * No additional HeapMem region.
- * HiAppMem contains the stack, loader, shared libraries and heap.
- * Stack on NetBSD/amd64 has prereserved 128MB.
- * Heap grows downwards (top-down).
- * ASLR must be disabled per-process or globally.
- */
- struct Mapping48AddressSpace {
- static const uptr kMetaShadowBeg = 0x300000000000ull;
- static const uptr kMetaShadowEnd = 0x340000000000ull;
- static const uptr kShadowBeg = 0x010000000000ull;
- static const uptr kShadowEnd = 0x100000000000ull;
- static const uptr kHeapMemBeg = 0x7b0000000000ull;
- static const uptr kHeapMemEnd = 0x7c0000000000ull;
- static const uptr kLoAppMemBeg = 0x000000001000ull;
- static const uptr kLoAppMemEnd = 0x008000000000ull;
- static const uptr kMidAppMemBeg = 0x550000000000ull;
- static const uptr kMidAppMemEnd = 0x568000000000ull;
- static const uptr kHiAppMemBeg = 0x7e8000000000ull;
- static const uptr kHiAppMemEnd = 0x800000000000ull;
- static const uptr kShadowMsk = 0x780000000000ull;
- static const uptr kShadowXor = 0x040000000000ull;
- static const uptr kShadowAdd = 0x000000000000ull;
- static const uptr kVdsoBeg = 0xf000000000000000ull;
- };
- /*
- C/C++ on linux/mips64 (40-bit VMA)
- 0000 0000 00 - 0100 0000 00: - (4 GB)
- 0100 0000 00 - 0200 0000 00: main binary (4 GB)
- 0200 0000 00 - 1200 0000 00: - (64 GB)
- 1200 0000 00 - 2200 0000 00: shadow (64 GB)
- 2200 0000 00 - 4000 0000 00: - (120 GB)
- 4000 0000 00 - 5000 0000 00: metainfo (memory blocks and sync objects) (64 GB)
- 5000 0000 00 - aa00 0000 00: - (360 GB)
- aa00 0000 00 - ab00 0000 00: main binary (PIE) (4 GB)
- ab00 0000 00 - fe00 0000 00: - (332 GB)
- fe00 0000 00 - ff00 0000 00: heap (4 GB)
- ff00 0000 00 - ff80 0000 00: - (2 GB)
- ff80 0000 00 - ffff ffff ff: modules and main thread stack (<2 GB)
- */
- struct MappingMips64_40 {
- static const uptr kMetaShadowBeg = 0x4000000000ull;
- static const uptr kMetaShadowEnd = 0x5000000000ull;
- static const uptr kShadowBeg = 0x1200000000ull;
- static const uptr kShadowEnd = 0x2200000000ull;
- static const uptr kHeapMemBeg = 0xfe00000000ull;
- static const uptr kHeapMemEnd = 0xff00000000ull;
- static const uptr kLoAppMemBeg = 0x0100000000ull;
- static const uptr kLoAppMemEnd = 0x0200000000ull;
- static const uptr kMidAppMemBeg = 0xaa00000000ull;
- static const uptr kMidAppMemEnd = 0xab00000000ull;
- static const uptr kHiAppMemBeg = 0xff80000000ull;
- static const uptr kHiAppMemEnd = 0xffffffffffull;
- static const uptr kShadowMsk = 0xf800000000ull;
- static const uptr kShadowXor = 0x0800000000ull;
- static const uptr kShadowAdd = 0x0000000000ull;
- static const uptr kVdsoBeg = 0xfffff00000ull;
- };
- /*
- C/C++ on Darwin/iOS/ARM64 (36-bit VMA, 64 GB VM)
- 0000 0000 00 - 0100 0000 00: - (4 GB)
- 0100 0000 00 - 0200 0000 00: main binary, modules, thread stacks (4 GB)
- 0200 0000 00 - 0300 0000 00: heap (4 GB)
- 0300 0000 00 - 0400 0000 00: - (4 GB)
- 0400 0000 00 - 0800 0000 00: shadow memory (16 GB)
- 0800 0000 00 - 0d00 0000 00: - (20 GB)
- 0d00 0000 00 - 0e00 0000 00: metainfo (4 GB)
- 0e00 0000 00 - 1000 0000 00: -
- */
- struct MappingAppleAarch64 {
- static const uptr kLoAppMemBeg = 0x0100000000ull;
- static const uptr kLoAppMemEnd = 0x0200000000ull;
- static const uptr kHeapMemBeg = 0x0200000000ull;
- static const uptr kHeapMemEnd = 0x0300000000ull;
- static const uptr kShadowBeg = 0x0400000000ull;
- static const uptr kShadowEnd = 0x0800000000ull;
- static const uptr kMetaShadowBeg = 0x0d00000000ull;
- static const uptr kMetaShadowEnd = 0x0e00000000ull;
- static const uptr kHiAppMemBeg = 0x0fc0000000ull;
- static const uptr kHiAppMemEnd = 0x0fc0000000ull;
- static const uptr kShadowMsk = 0x0ull;
- static const uptr kShadowXor = 0x0ull;
- static const uptr kShadowAdd = 0x0200000000ull;
- static const uptr kVdsoBeg = 0x7000000000000000ull;
- static const uptr kMidAppMemBeg = 0;
- static const uptr kMidAppMemEnd = 0;
- };
- /*
- C/C++ on linux/aarch64 (39-bit VMA)
- 0000 0010 00 - 0100 0000 00: main binary
- 0100 0000 00 - 0400 0000 00: -
- 0400 0000 00 - 1000 0000 00: shadow memory
- 2000 0000 00 - 3100 0000 00: -
- 3100 0000 00 - 3400 0000 00: metainfo
- 3400 0000 00 - 5500 0000 00: -
- 5500 0000 00 - 5600 0000 00: main binary (PIE)
- 5600 0000 00 - 7c00 0000 00: -
- 7c00 0000 00 - 7d00 0000 00: heap
- 7d00 0000 00 - 7fff ffff ff: modules and main thread stack
- */
- struct MappingAarch64_39 {
- static const uptr kLoAppMemBeg = 0x0000001000ull;
- static const uptr kLoAppMemEnd = 0x0100000000ull;
- static const uptr kShadowBeg = 0x0400000000ull;
- static const uptr kShadowEnd = 0x1000000000ull;
- static const uptr kMetaShadowBeg = 0x3100000000ull;
- static const uptr kMetaShadowEnd = 0x3400000000ull;
- static const uptr kMidAppMemBeg = 0x5500000000ull;
- static const uptr kMidAppMemEnd = 0x5600000000ull;
- static const uptr kHeapMemBeg = 0x7c00000000ull;
- static const uptr kHeapMemEnd = 0x7d00000000ull;
- static const uptr kHiAppMemBeg = 0x7e00000000ull;
- static const uptr kHiAppMemEnd = 0x7fffffffffull;
- static const uptr kShadowMsk = 0x7800000000ull;
- static const uptr kShadowXor = 0x0200000000ull;
- static const uptr kShadowAdd = 0x0000000000ull;
- static const uptr kVdsoBeg = 0x7f00000000ull;
- };
- /*
- C/C++ on linux/aarch64 (42-bit VMA)
- 00000 0010 00 - 01000 0000 00: main binary
- 01000 0000 00 - 08000 0000 00: -
- 08000 0000 00 - 10000 0000 00: shadow memory
- 10000 0000 00 - 26000 0000 00: -
- 26000 0000 00 - 28000 0000 00: metainfo
- 28000 0000 00 - 2aa00 0000 00: -
- 2aa00 0000 00 - 2ab00 0000 00: main binary (PIE)
- 2ab00 0000 00 - 3e000 0000 00: -
- 3e000 0000 00 - 3f000 0000 00: heap
- 3f000 0000 00 - 3ffff ffff ff: modules and main thread stack
- */
- struct MappingAarch64_42 {
- static const uptr kBroken = kBrokenReverseMapping;
- static const uptr kLoAppMemBeg = 0x00000001000ull;
- static const uptr kLoAppMemEnd = 0x01000000000ull;
- static const uptr kShadowBeg = 0x08000000000ull;
- static const uptr kShadowEnd = 0x10000000000ull;
- static const uptr kMetaShadowBeg = 0x26000000000ull;
- static const uptr kMetaShadowEnd = 0x28000000000ull;
- static const uptr kMidAppMemBeg = 0x2aa00000000ull;
- static const uptr kMidAppMemEnd = 0x2ab00000000ull;
- static const uptr kHeapMemBeg = 0x3e000000000ull;
- static const uptr kHeapMemEnd = 0x3f000000000ull;
- static const uptr kHiAppMemBeg = 0x3f000000000ull;
- static const uptr kHiAppMemEnd = 0x3ffffffffffull;
- static const uptr kShadowMsk = 0x3c000000000ull;
- static const uptr kShadowXor = 0x04000000000ull;
- static const uptr kShadowAdd = 0x00000000000ull;
- static const uptr kVdsoBeg = 0x37f00000000ull;
- };
- struct MappingAarch64_48 {
- static const uptr kLoAppMemBeg = 0x0000000001000ull;
- static const uptr kLoAppMemEnd = 0x0000200000000ull;
- static const uptr kShadowBeg = 0x0001000000000ull;
- static const uptr kShadowEnd = 0x0002000000000ull;
- static const uptr kMetaShadowBeg = 0x0005000000000ull;
- static const uptr kMetaShadowEnd = 0x0006000000000ull;
- static const uptr kMidAppMemBeg = 0x0aaaa00000000ull;
- static const uptr kMidAppMemEnd = 0x0aaaf00000000ull;
- static const uptr kHeapMemBeg = 0x0ffff00000000ull;
- static const uptr kHeapMemEnd = 0x0ffff00000000ull;
- static const uptr kHiAppMemBeg = 0x0ffff00000000ull;
- static const uptr kHiAppMemEnd = 0x1000000000000ull;
- static const uptr kShadowMsk = 0x0fff800000000ull;
- static const uptr kShadowXor = 0x0000800000000ull;
- static const uptr kShadowAdd = 0x0000000000000ull;
- static const uptr kVdsoBeg = 0xffff000000000ull;
- };
- /*
- C/C++ on linux/powerpc64 (44-bit VMA)
- 0000 0000 0100 - 0001 0000 0000: main binary
- 0001 0000 0000 - 0001 0000 0000: -
- 0001 0000 0000 - 0b00 0000 0000: shadow
- 0b00 0000 0000 - 0b00 0000 0000: -
- 0b00 0000 0000 - 0d00 0000 0000: metainfo (memory blocks and sync objects)
- 0d00 0000 0000 - 0f00 0000 0000: -
- 0f00 0000 0000 - 0f50 0000 0000: heap
- 0f50 0000 0000 - 0f60 0000 0000: -
- 0f60 0000 0000 - 1000 0000 0000: modules and main thread stack
- */
- struct MappingPPC64_44 {
- static const uptr kBroken =
- kBrokenMapping | kBrokenReverseMapping | kBrokenLinearity;
- static const uptr kMetaShadowBeg = 0x0b0000000000ull;
- static const uptr kMetaShadowEnd = 0x0d0000000000ull;
- static const uptr kShadowBeg = 0x000100000000ull;
- static const uptr kShadowEnd = 0x0b0000000000ull;
- static const uptr kLoAppMemBeg = 0x000000000100ull;
- static const uptr kLoAppMemEnd = 0x000100000000ull;
- static const uptr kHeapMemBeg = 0x0f0000000000ull;
- static const uptr kHeapMemEnd = 0x0f5000000000ull;
- static const uptr kHiAppMemBeg = 0x0f6000000000ull;
- static const uptr kHiAppMemEnd = 0x100000000000ull; // 44 bits
- static const uptr kShadowMsk = 0x0f0000000000ull;
- static const uptr kShadowXor = 0x002100000000ull;
- static const uptr kShadowAdd = 0x000000000000ull;
- static const uptr kVdsoBeg = 0x3c0000000000000ull;
- static const uptr kMidAppMemBeg = 0;
- static const uptr kMidAppMemEnd = 0;
- };
- /*
- C/C++ on linux/powerpc64 (46-bit VMA)
- 0000 0000 1000 - 0100 0000 0000: main binary
- 0100 0000 0000 - 0200 0000 0000: -
- 0100 0000 0000 - 0800 0000 0000: shadow
- 0800 0000 0000 - 1000 0000 0000: -
- 1000 0000 0000 - 1200 0000 0000: metainfo (memory blocks and sync objects)
- 1200 0000 0000 - 3d00 0000 0000: -
- 3d00 0000 0000 - 3e00 0000 0000: heap
- 3e00 0000 0000 - 3e80 0000 0000: -
- 3e80 0000 0000 - 4000 0000 0000: modules and main thread stack
- */
- struct MappingPPC64_46 {
- static const uptr kMetaShadowBeg = 0x100000000000ull;
- static const uptr kMetaShadowEnd = 0x120000000000ull;
- static const uptr kShadowBeg = 0x010000000000ull;
- static const uptr kShadowEnd = 0x080000000000ull;
- static const uptr kHeapMemBeg = 0x3d0000000000ull;
- static const uptr kHeapMemEnd = 0x3e0000000000ull;
- static const uptr kLoAppMemBeg = 0x000000001000ull;
- static const uptr kLoAppMemEnd = 0x010000000000ull;
- static const uptr kHiAppMemBeg = 0x3e8000000000ull;
- static const uptr kHiAppMemEnd = 0x400000000000ull; // 46 bits
- static const uptr kShadowMsk = 0x3c0000000000ull;
- static const uptr kShadowXor = 0x020000000000ull;
- static const uptr kShadowAdd = 0x000000000000ull;
- static const uptr kVdsoBeg = 0x7800000000000000ull;
- static const uptr kMidAppMemBeg = 0;
- static const uptr kMidAppMemEnd = 0;
- };
- /*
- C/C++ on linux/powerpc64 (47-bit VMA)
- 0000 0000 1000 - 0100 0000 0000: main binary
- 0100 0000 0000 - 0200 0000 0000: -
- 0100 0000 0000 - 0800 0000 0000: shadow
- 0800 0000 0000 - 1000 0000 0000: -
- 1000 0000 0000 - 1200 0000 0000: metainfo (memory blocks and sync objects)
- 1200 0000 0000 - 7d00 0000 0000: -
- 7d00 0000 0000 - 7e00 0000 0000: heap
- 7e00 0000 0000 - 7e80 0000 0000: -
- 7e80 0000 0000 - 8000 0000 0000: modules and main thread stack
- */
- struct MappingPPC64_47 {
- static const uptr kMetaShadowBeg = 0x100000000000ull;
- static const uptr kMetaShadowEnd = 0x120000000000ull;
- static const uptr kShadowBeg = 0x010000000000ull;
- static const uptr kShadowEnd = 0x080000000000ull;
- static const uptr kHeapMemBeg = 0x7d0000000000ull;
- static const uptr kHeapMemEnd = 0x7e0000000000ull;
- static const uptr kLoAppMemBeg = 0x000000001000ull;
- static const uptr kLoAppMemEnd = 0x010000000000ull;
- static const uptr kHiAppMemBeg = 0x7e8000000000ull;
- static const uptr kHiAppMemEnd = 0x800000000000ull; // 47 bits
- static const uptr kShadowMsk = 0x7c0000000000ull;
- static const uptr kShadowXor = 0x020000000000ull;
- static const uptr kShadowAdd = 0x000000000000ull;
- static const uptr kVdsoBeg = 0x7800000000000000ull;
- static const uptr kMidAppMemBeg = 0;
- static const uptr kMidAppMemEnd = 0;
- };
- /*
- C/C++ on linux/s390x
- While the kernel provides a 64-bit address space, we have to restrict ourselves
- to 48 bits due to how e.g. SyncVar::GetId() works.
- 0000 0000 1000 - 0e00 0000 0000: binary, modules, stacks - 14 TiB
- 0e00 0000 0000 - 2000 0000 0000: -
- 2000 0000 0000 - 4000 0000 0000: shadow - 32TiB (2 * app)
- 4000 0000 0000 - 9000 0000 0000: -
- 9000 0000 0000 - 9800 0000 0000: metainfo - 8TiB (0.5 * app)
- 9800 0000 0000 - be00 0000 0000: -
- be00 0000 0000 - c000 0000 0000: heap - 2TiB (max supported by the allocator)
- */
- struct MappingS390x {
- static const uptr kMetaShadowBeg = 0x900000000000ull;
- static const uptr kMetaShadowEnd = 0x980000000000ull;
- static const uptr kShadowBeg = 0x200000000000ull;
- static const uptr kShadowEnd = 0x400000000000ull;
- static const uptr kHeapMemBeg = 0xbe0000000000ull;
- static const uptr kHeapMemEnd = 0xc00000000000ull;
- static const uptr kLoAppMemBeg = 0x000000001000ull;
- static const uptr kLoAppMemEnd = 0x0e0000000000ull;
- static const uptr kHiAppMemBeg = 0xc00000004000ull;
- static const uptr kHiAppMemEnd = 0xc00000004000ull;
- static const uptr kShadowMsk = 0xb00000000000ull;
- static const uptr kShadowXor = 0x100000000000ull;
- static const uptr kShadowAdd = 0x000000000000ull;
- static const uptr kVdsoBeg = 0xfffffffff000ull;
- static const uptr kMidAppMemBeg = 0;
- static const uptr kMidAppMemEnd = 0;
- };
- /* Go on linux, darwin and freebsd on x86_64
- 0000 0000 1000 - 0000 1000 0000: executable
- 0000 1000 0000 - 00c0 0000 0000: -
- 00c0 0000 0000 - 00e0 0000 0000: heap
- 00e0 0000 0000 - 2000 0000 0000: -
- 2000 0000 0000 - 21c0 0000 0000: shadow
- 21c0 0000 0000 - 3000 0000 0000: -
- 3000 0000 0000 - 4000 0000 0000: metainfo (memory blocks and sync objects)
- 4000 0000 0000 - 8000 0000 0000: -
- */
- struct MappingGo48 {
- static const uptr kMetaShadowBeg = 0x300000000000ull;
- static const uptr kMetaShadowEnd = 0x400000000000ull;
- static const uptr kShadowBeg = 0x200000000000ull;
- static const uptr kShadowEnd = 0x21c000000000ull;
- static const uptr kLoAppMemBeg = 0x000000001000ull;
- static const uptr kLoAppMemEnd = 0x00e000000000ull;
- static const uptr kMidAppMemBeg = 0;
- static const uptr kMidAppMemEnd = 0;
- static const uptr kHiAppMemBeg = 0;
- static const uptr kHiAppMemEnd = 0;
- static const uptr kHeapMemBeg = 0;
- static const uptr kHeapMemEnd = 0;
- static const uptr kVdsoBeg = 0;
- static const uptr kShadowMsk = 0;
- static const uptr kShadowXor = 0;
- static const uptr kShadowAdd = 0x200000000000ull;
- };
- /* Go on windows
- 0000 0000 1000 - 0000 1000 0000: executable
- 0000 1000 0000 - 00f8 0000 0000: -
- 00c0 0000 0000 - 00e0 0000 0000: heap
- 00e0 0000 0000 - 0100 0000 0000: -
- 0100 0000 0000 - 0300 0000 0000: shadow
- 0300 0000 0000 - 0700 0000 0000: -
- 0700 0000 0000 - 0770 0000 0000: metainfo (memory blocks and sync objects)
- 07d0 0000 0000 - 8000 0000 0000: -
- */
- struct MappingGoWindows {
- static const uptr kMetaShadowBeg = 0x070000000000ull;
- static const uptr kMetaShadowEnd = 0x077000000000ull;
- static const uptr kShadowBeg = 0x010000000000ull;
- static const uptr kShadowEnd = 0x030000000000ull;
- static const uptr kLoAppMemBeg = 0x000000001000ull;
- static const uptr kLoAppMemEnd = 0x00e000000000ull;
- static const uptr kMidAppMemBeg = 0;
- static const uptr kMidAppMemEnd = 0;
- static const uptr kHiAppMemBeg = 0;
- static const uptr kHiAppMemEnd = 0;
- static const uptr kHeapMemBeg = 0;
- static const uptr kHeapMemEnd = 0;
- static const uptr kVdsoBeg = 0;
- static const uptr kShadowMsk = 0;
- static const uptr kShadowXor = 0;
- static const uptr kShadowAdd = 0x010000000000ull;
- };
- /* Go on linux/powerpc64 (46-bit VMA)
- 0000 0000 1000 - 0000 1000 0000: executable
- 0000 1000 0000 - 00c0 0000 0000: -
- 00c0 0000 0000 - 00e0 0000 0000: heap
- 00e0 0000 0000 - 2000 0000 0000: -
- 2000 0000 0000 - 21c0 0000 0000: shadow
- 21c0 0000 0000 - 2400 0000 0000: -
- 2400 0000 0000 - 2470 0000 0000: metainfo (memory blocks and sync objects)
- 2470 0000 0000 - 4000 0000 0000: -
- */
- struct MappingGoPPC64_46 {
- static const uptr kMetaShadowBeg = 0x240000000000ull;
- static const uptr kMetaShadowEnd = 0x247000000000ull;
- static const uptr kShadowBeg = 0x200000000000ull;
- static const uptr kShadowEnd = 0x21c000000000ull;
- static const uptr kLoAppMemBeg = 0x000000001000ull;
- static const uptr kLoAppMemEnd = 0x00e000000000ull;
- static const uptr kMidAppMemBeg = 0;
- static const uptr kMidAppMemEnd = 0;
- static const uptr kHiAppMemBeg = 0;
- static const uptr kHiAppMemEnd = 0;
- static const uptr kHeapMemBeg = 0;
- static const uptr kHeapMemEnd = 0;
- static const uptr kVdsoBeg = 0;
- static const uptr kShadowMsk = 0;
- static const uptr kShadowXor = 0;
- static const uptr kShadowAdd = 0x200000000000ull;
- };
- /* Go on linux/powerpc64 (47-bit VMA)
- 0000 0000 1000 - 0000 1000 0000: executable
- 0000 1000 0000 - 00c0 0000 0000: -
- 00c0 0000 0000 - 00e0 0000 0000: heap
- 00e0 0000 0000 - 2000 0000 0000: -
- 2000 0000 0000 - 2800 0000 0000: shadow
- 2800 0000 0000 - 3000 0000 0000: -
- 3000 0000 0000 - 3200 0000 0000: metainfo (memory blocks and sync objects)
- 3200 0000 0000 - 8000 0000 0000: -
- */
- struct MappingGoPPC64_47 {
- static const uptr kMetaShadowBeg = 0x300000000000ull;
- static const uptr kMetaShadowEnd = 0x320000000000ull;
- static const uptr kShadowBeg = 0x200000000000ull;
- static const uptr kShadowEnd = 0x280000000000ull;
- static const uptr kLoAppMemBeg = 0x000000001000ull;
- static const uptr kLoAppMemEnd = 0x00e000000000ull;
- static const uptr kMidAppMemBeg = 0;
- static const uptr kMidAppMemEnd = 0;
- static const uptr kHiAppMemBeg = 0;
- static const uptr kHiAppMemEnd = 0;
- static const uptr kHeapMemBeg = 0;
- static const uptr kHeapMemEnd = 0;
- static const uptr kVdsoBeg = 0;
- static const uptr kShadowMsk = 0;
- static const uptr kShadowXor = 0;
- static const uptr kShadowAdd = 0x200000000000ull;
- };
- /* Go on linux/aarch64 (48-bit VMA) and darwin/aarch64 (47-bit VMA)
- 0000 0000 1000 - 0000 1000 0000: executable
- 0000 1000 0000 - 00c0 0000 0000: -
- 00c0 0000 0000 - 00e0 0000 0000: heap
- 00e0 0000 0000 - 2000 0000 0000: -
- 2000 0000 0000 - 2800 0000 0000: shadow
- 2800 0000 0000 - 3000 0000 0000: -
- 3000 0000 0000 - 3200 0000 0000: metainfo (memory blocks and sync objects)
- 3200 0000 0000 - 8000 0000 0000: -
- */
- struct MappingGoAarch64 {
- static const uptr kMetaShadowBeg = 0x300000000000ull;
- static const uptr kMetaShadowEnd = 0x320000000000ull;
- static const uptr kShadowBeg = 0x200000000000ull;
- static const uptr kShadowEnd = 0x280000000000ull;
- static const uptr kLoAppMemBeg = 0x000000001000ull;
- static const uptr kLoAppMemEnd = 0x00e000000000ull;
- static const uptr kMidAppMemBeg = 0;
- static const uptr kMidAppMemEnd = 0;
- static const uptr kHiAppMemBeg = 0;
- static const uptr kHiAppMemEnd = 0;
- static const uptr kHeapMemBeg = 0;
- static const uptr kHeapMemEnd = 0;
- static const uptr kVdsoBeg = 0;
- static const uptr kShadowMsk = 0;
- static const uptr kShadowXor = 0;
- static const uptr kShadowAdd = 0x200000000000ull;
- };
- /*
- Go on linux/mips64 (47-bit VMA)
- 0000 0000 1000 - 0000 1000 0000: executable
- 0000 1000 0000 - 00c0 0000 0000: -
- 00c0 0000 0000 - 00e0 0000 0000: heap
- 00e0 0000 0000 - 2000 0000 0000: -
- 2000 0000 0000 - 2800 0000 0000: shadow
- 2800 0000 0000 - 3000 0000 0000: -
- 3000 0000 0000 - 3200 0000 0000: metainfo (memory blocks and sync objects)
- 3200 0000 0000 - 8000 0000 0000: -
- */
- struct MappingGoMips64_47 {
- static const uptr kMetaShadowBeg = 0x300000000000ull;
- static const uptr kMetaShadowEnd = 0x320000000000ull;
- static const uptr kShadowBeg = 0x200000000000ull;
- static const uptr kShadowEnd = 0x280000000000ull;
- static const uptr kLoAppMemBeg = 0x000000001000ull;
- static const uptr kLoAppMemEnd = 0x00e000000000ull;
- static const uptr kMidAppMemBeg = 0;
- static const uptr kMidAppMemEnd = 0;
- static const uptr kHiAppMemBeg = 0;
- static const uptr kHiAppMemEnd = 0;
- static const uptr kHeapMemBeg = 0;
- static const uptr kHeapMemEnd = 0;
- static const uptr kVdsoBeg = 0;
- static const uptr kShadowMsk = 0;
- static const uptr kShadowXor = 0;
- static const uptr kShadowAdd = 0x200000000000ull;
- };
- /*
- Go on linux/s390x
- 0000 0000 1000 - 1000 0000 0000: executable and heap - 16 TiB
- 1000 0000 0000 - 4000 0000 0000: -
- 4000 0000 0000 - 6000 0000 0000: shadow - 64TiB (4 * app)
- 6000 0000 0000 - 9000 0000 0000: -
- 9000 0000 0000 - 9800 0000 0000: metainfo - 8TiB (0.5 * app)
- */
- struct MappingGoS390x {
- static const uptr kMetaShadowBeg = 0x900000000000ull;
- static const uptr kMetaShadowEnd = 0x980000000000ull;
- static const uptr kShadowBeg = 0x400000000000ull;
- static const uptr kShadowEnd = 0x600000000000ull;
- static const uptr kLoAppMemBeg = 0x000000001000ull;
- static const uptr kLoAppMemEnd = 0x100000000000ull;
- static const uptr kMidAppMemBeg = 0;
- static const uptr kMidAppMemEnd = 0;
- static const uptr kHiAppMemBeg = 0;
- static const uptr kHiAppMemEnd = 0;
- static const uptr kHeapMemBeg = 0;
- static const uptr kHeapMemEnd = 0;
- static const uptr kVdsoBeg = 0;
- static const uptr kShadowMsk = 0;
- static const uptr kShadowXor = 0;
- static const uptr kShadowAdd = 0x400000000000ull;
- };
- extern uptr vmaSize;
- template <typename Func, typename Arg>
- ALWAYS_INLINE auto SelectMapping(Arg arg) {
- #if SANITIZER_GO
- # if defined(__powerpc64__)
- switch (vmaSize) {
- case 46:
- return Func::template Apply<MappingGoPPC64_46>(arg);
- case 47:
- return Func::template Apply<MappingGoPPC64_47>(arg);
- }
- # elif defined(__mips64)
- return Func::template Apply<MappingGoMips64_47>(arg);
- # elif defined(__s390x__)
- return Func::template Apply<MappingGoS390x>(arg);
- # elif defined(__aarch64__)
- return Func::template Apply<MappingGoAarch64>(arg);
- # elif SANITIZER_WINDOWS
- return Func::template Apply<MappingGoWindows>(arg);
- # else
- return Func::template Apply<MappingGo48>(arg);
- # endif
- #else // SANITIZER_GO
- # if SANITIZER_IOS && !SANITIZER_IOSSIM
- return Func::template Apply<MappingAppleAarch64>(arg);
- # elif defined(__x86_64__) || SANITIZER_MAC
- return Func::template Apply<Mapping48AddressSpace>(arg);
- # elif defined(__aarch64__)
- switch (vmaSize) {
- case 39:
- return Func::template Apply<MappingAarch64_39>(arg);
- case 42:
- return Func::template Apply<MappingAarch64_42>(arg);
- case 48:
- return Func::template Apply<MappingAarch64_48>(arg);
- }
- # elif defined(__powerpc64__)
- switch (vmaSize) {
- case 44:
- return Func::template Apply<MappingPPC64_44>(arg);
- case 46:
- return Func::template Apply<MappingPPC64_46>(arg);
- case 47:
- return Func::template Apply<MappingPPC64_47>(arg);
- }
- # elif defined(__mips64)
- return Func::template Apply<MappingMips64_40>(arg);
- # elif defined(__s390x__)
- return Func::template Apply<MappingS390x>(arg);
- # else
- # error "unsupported platform"
- # endif
- #endif
- Die();
- }
- template <typename Func>
- void ForEachMapping() {
- Func::template Apply<Mapping48AddressSpace>();
- Func::template Apply<MappingMips64_40>();
- Func::template Apply<MappingAppleAarch64>();
- Func::template Apply<MappingAarch64_39>();
- Func::template Apply<MappingAarch64_42>();
- Func::template Apply<MappingAarch64_48>();
- Func::template Apply<MappingPPC64_44>();
- Func::template Apply<MappingPPC64_46>();
- Func::template Apply<MappingPPC64_47>();
- Func::template Apply<MappingS390x>();
- Func::template Apply<MappingGo48>();
- Func::template Apply<MappingGoWindows>();
- Func::template Apply<MappingGoPPC64_46>();
- Func::template Apply<MappingGoPPC64_47>();
- Func::template Apply<MappingGoAarch64>();
- Func::template Apply<MappingGoMips64_47>();
- Func::template Apply<MappingGoS390x>();
- }
- enum MappingType {
- kLoAppMemBeg,
- kLoAppMemEnd,
- kHiAppMemBeg,
- kHiAppMemEnd,
- kMidAppMemBeg,
- kMidAppMemEnd,
- kHeapMemBeg,
- kHeapMemEnd,
- kShadowBeg,
- kShadowEnd,
- kMetaShadowBeg,
- kMetaShadowEnd,
- kVdsoBeg,
- };
- struct MappingField {
- template <typename Mapping>
- static uptr Apply(MappingType type) {
- switch (type) {
- case kLoAppMemBeg:
- return Mapping::kLoAppMemBeg;
- case kLoAppMemEnd:
- return Mapping::kLoAppMemEnd;
- case kMidAppMemBeg:
- return Mapping::kMidAppMemBeg;
- case kMidAppMemEnd:
- return Mapping::kMidAppMemEnd;
- case kHiAppMemBeg:
- return Mapping::kHiAppMemBeg;
- case kHiAppMemEnd:
- return Mapping::kHiAppMemEnd;
- case kHeapMemBeg:
- return Mapping::kHeapMemBeg;
- case kHeapMemEnd:
- return Mapping::kHeapMemEnd;
- case kVdsoBeg:
- return Mapping::kVdsoBeg;
- case kShadowBeg:
- return Mapping::kShadowBeg;
- case kShadowEnd:
- return Mapping::kShadowEnd;
- case kMetaShadowBeg:
- return Mapping::kMetaShadowBeg;
- case kMetaShadowEnd:
- return Mapping::kMetaShadowEnd;
- }
- Die();
- }
- };
- ALWAYS_INLINE
- uptr LoAppMemBeg(void) { return SelectMapping<MappingField>(kLoAppMemBeg); }
- ALWAYS_INLINE
- uptr LoAppMemEnd(void) { return SelectMapping<MappingField>(kLoAppMemEnd); }
- ALWAYS_INLINE
- uptr MidAppMemBeg(void) { return SelectMapping<MappingField>(kMidAppMemBeg); }
- ALWAYS_INLINE
- uptr MidAppMemEnd(void) { return SelectMapping<MappingField>(kMidAppMemEnd); }
- ALWAYS_INLINE
- uptr HeapMemBeg(void) { return SelectMapping<MappingField>(kHeapMemBeg); }
- ALWAYS_INLINE
- uptr HeapMemEnd(void) { return SelectMapping<MappingField>(kHeapMemEnd); }
- ALWAYS_INLINE
- uptr HiAppMemBeg(void) { return SelectMapping<MappingField>(kHiAppMemBeg); }
- ALWAYS_INLINE
- uptr HiAppMemEnd(void) { return SelectMapping<MappingField>(kHiAppMemEnd); }
- ALWAYS_INLINE
- uptr VdsoBeg(void) { return SelectMapping<MappingField>(kVdsoBeg); }
- ALWAYS_INLINE
- uptr ShadowBeg(void) { return SelectMapping<MappingField>(kShadowBeg); }
- ALWAYS_INLINE
- uptr ShadowEnd(void) { return SelectMapping<MappingField>(kShadowEnd); }
- ALWAYS_INLINE
- uptr MetaShadowBeg(void) { return SelectMapping<MappingField>(kMetaShadowBeg); }
- ALWAYS_INLINE
- uptr MetaShadowEnd(void) { return SelectMapping<MappingField>(kMetaShadowEnd); }
- struct IsAppMemImpl {
- template <typename Mapping>
- static bool Apply(uptr mem) {
- return (mem >= Mapping::kHeapMemBeg && mem < Mapping::kHeapMemEnd) ||
- (mem >= Mapping::kMidAppMemBeg && mem < Mapping::kMidAppMemEnd) ||
- (mem >= Mapping::kLoAppMemBeg && mem < Mapping::kLoAppMemEnd) ||
- (mem >= Mapping::kHiAppMemBeg && mem < Mapping::kHiAppMemEnd);
- }
- };
- ALWAYS_INLINE
- bool IsAppMem(uptr mem) { return SelectMapping<IsAppMemImpl>(mem); }
- struct IsShadowMemImpl {
- template <typename Mapping>
- static bool Apply(uptr mem) {
- return mem >= Mapping::kShadowBeg && mem <= Mapping::kShadowEnd;
- }
- };
- ALWAYS_INLINE
- bool IsShadowMem(RawShadow *p) {
- return SelectMapping<IsShadowMemImpl>(reinterpret_cast<uptr>(p));
- }
- struct IsMetaMemImpl {
- template <typename Mapping>
- static bool Apply(uptr mem) {
- return mem >= Mapping::kMetaShadowBeg && mem <= Mapping::kMetaShadowEnd;
- }
- };
- ALWAYS_INLINE
- bool IsMetaMem(const u32 *p) {
- return SelectMapping<IsMetaMemImpl>(reinterpret_cast<uptr>(p));
- }
- struct MemToShadowImpl {
- template <typename Mapping>
- static uptr Apply(uptr x) {
- DCHECK(IsAppMemImpl::Apply<Mapping>(x));
- return (((x) & ~(Mapping::kShadowMsk | (kShadowCell - 1))) ^
- Mapping::kShadowXor) *
- kShadowMultiplier +
- Mapping::kShadowAdd;
- }
- };
- ALWAYS_INLINE
- RawShadow *MemToShadow(uptr x) {
- return reinterpret_cast<RawShadow *>(SelectMapping<MemToShadowImpl>(x));
- }
- struct MemToMetaImpl {
- template <typename Mapping>
- static u32 *Apply(uptr x) {
- DCHECK(IsAppMemImpl::Apply<Mapping>(x));
- return (u32 *)(((((x) & ~(Mapping::kShadowMsk | (kMetaShadowCell - 1)))) /
- kMetaShadowCell * kMetaShadowSize) |
- Mapping::kMetaShadowBeg);
- }
- };
- ALWAYS_INLINE
- u32 *MemToMeta(uptr x) { return SelectMapping<MemToMetaImpl>(x); }
- struct ShadowToMemImpl {
- template <typename Mapping>
- static uptr Apply(uptr sp) {
- if (!IsShadowMemImpl::Apply<Mapping>(sp))
- return 0;
- // The shadow mapping is non-linear and we've lost some bits, so we don't
- // have an easy way to restore the original app address. But the mapping is
- // a bijection, so we try to restore the address as belonging to
- // low/mid/high range consecutively and see if shadow->app->shadow mapping
- // gives us the same address.
- uptr p =
- ((sp - Mapping::kShadowAdd) / kShadowMultiplier) ^ Mapping::kShadowXor;
- if (p >= Mapping::kLoAppMemBeg && p < Mapping::kLoAppMemEnd &&
- MemToShadowImpl::Apply<Mapping>(p) == sp)
- return p;
- if (Mapping::kMidAppMemBeg) {
- uptr p_mid = p + (Mapping::kMidAppMemBeg & Mapping::kShadowMsk);
- if (p_mid >= Mapping::kMidAppMemBeg && p_mid < Mapping::kMidAppMemEnd &&
- MemToShadowImpl::Apply<Mapping>(p_mid) == sp)
- return p_mid;
- }
- return p | Mapping::kShadowMsk;
- }
- };
- ALWAYS_INLINE
- uptr ShadowToMem(RawShadow *s) {
- return SelectMapping<ShadowToMemImpl>(reinterpret_cast<uptr>(s));
- }
- // Compresses addr to kCompressedAddrBits stored in least significant bits.
- ALWAYS_INLINE uptr CompressAddr(uptr addr) {
- return addr & ((1ull << kCompressedAddrBits) - 1);
- }
- struct RestoreAddrImpl {
- typedef uptr Result;
- template <typename Mapping>
- static Result Apply(uptr addr) {
- // To restore the address we go over all app memory ranges and check if top
- // 3 bits of the compressed addr match that of the app range. If yes, we
- // assume that the compressed address come from that range and restore the
- // missing top bits to match the app range address.
- const uptr ranges[] = {
- Mapping::kLoAppMemBeg, Mapping::kLoAppMemEnd, Mapping::kMidAppMemBeg,
- Mapping::kMidAppMemEnd, Mapping::kHiAppMemBeg, Mapping::kHiAppMemEnd,
- Mapping::kHeapMemBeg, Mapping::kHeapMemEnd,
- };
- const uptr indicator = 0x0e0000000000ull;
- const uptr ind_lsb = 1ull << LeastSignificantSetBitIndex(indicator);
- for (uptr i = 0; i < ARRAY_SIZE(ranges); i += 2) {
- uptr beg = ranges[i];
- uptr end = ranges[i + 1];
- if (beg == end)
- continue;
- for (uptr p = beg; p < end; p = RoundDown(p + ind_lsb, ind_lsb)) {
- if ((addr & indicator) == (p & indicator))
- return addr | (p & ~(ind_lsb - 1));
- }
- }
- Printf("ThreadSanitizer: failed to restore address 0x%zx\n", addr);
- Die();
- }
- };
- // Restores compressed addr from kCompressedAddrBits to full representation.
- // This is called only during reporting and is not performance-critical.
- inline uptr RestoreAddr(uptr addr) {
- return SelectMapping<RestoreAddrImpl>(addr);
- }
- void InitializePlatform();
- void InitializePlatformEarly();
- void CheckAndProtect();
- void InitializeShadowMemoryPlatform();
- void WriteMemoryProfile(char *buf, uptr buf_size, u64 uptime_ns);
- int ExtractResolvFDs(void *state, int *fds, int nfd);
- int ExtractRecvmsgFDs(void *msg, int *fds, int nfd);
- uptr ExtractLongJmpSp(uptr *env);
- void ImitateTlsWrite(ThreadState *thr, uptr tls_addr, uptr tls_size);
- int call_pthread_cancel_with_cleanup(int (*fn)(void *arg),
- void (*cleanup)(void *arg), void *arg);
- void DestroyThreadState();
- void PlatformCleanUpThreadState(ThreadState *thr);
- } // namespace __tsan
- #endif // TSAN_PLATFORM_H
|