1245614Sandrew//===-- msan.h --------------------------------------------------*- C++ -*-===// 2245614Sandrew// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6245614Sandrew// 7245614Sandrew//===----------------------------------------------------------------------===// 8245614Sandrew// 9245614Sandrew// This file is a part of MemorySanitizer. 10245614Sandrew// 11245614Sandrew// Private MSan header. 12245614Sandrew//===----------------------------------------------------------------------===// 13245614Sandrew 14245614Sandrew#ifndef MSAN_H 15245614Sandrew#define MSAN_H 16245614Sandrew 17251034Sed#include "sanitizer_common/sanitizer_flags.h" 18245614Sandrew#include "sanitizer_common/sanitizer_internal_defs.h" 19245614Sandrew#include "sanitizer_common/sanitizer_stacktrace.h" 20251034Sed#include "msan_interface_internal.h" 21245614Sandrew#include "msan_flags.h" 22288943Sdim#include "ubsan/ubsan_platform.h" 23245614Sandrew 24251034Sed#ifndef MSAN_REPLACE_OPERATORS_NEW_AND_DELETE 25251034Sed# define MSAN_REPLACE_OPERATORS_NEW_AND_DELETE 1 26251034Sed#endif 27251034Sed 28288943Sdim#ifndef MSAN_CONTAINS_UBSAN 29288943Sdim# define MSAN_CONTAINS_UBSAN CAN_SANITIZE_UB 30288943Sdim#endif 31288943Sdim 32280031Sdimstruct MappingDesc { 33280031Sdim uptr start; 34280031Sdim uptr end; 35280031Sdim enum Type { 36280031Sdim INVALID, APP, SHADOW, ORIGIN 37280031Sdim } type; 38280031Sdim const char *name; 39280031Sdim}; 40276789Sdim 41276789Sdim 42280031Sdim#if SANITIZER_LINUX && defined(__mips64) 43276789Sdim 44314564Sdim// MIPS64 maps: 45314564Sdim// - 0x0000000000-0x0200000000: Program own segments 46314564Sdim// - 0xa200000000-0xc000000000: PIE program segments 47314564Sdim// - 0xe200000000-0xffffffffff: libraries segments. 48280031Sdimconst MappingDesc kMemoryLayout[] = { 49314564Sdim {0x000000000000ULL, 0x000200000000ULL, MappingDesc::APP, "app-1"}, 50314564Sdim {0x000200000000ULL, 0x002200000000ULL, MappingDesc::INVALID, "invalid"}, 51314564Sdim {0x002200000000ULL, 0x004000000000ULL, MappingDesc::SHADOW, "shadow-2"}, 52314564Sdim {0x004000000000ULL, 0x004200000000ULL, MappingDesc::INVALID, "invalid"}, 53314564Sdim {0x004200000000ULL, 0x006000000000ULL, MappingDesc::ORIGIN, "origin-2"}, 54314564Sdim {0x006000000000ULL, 0x006200000000ULL, MappingDesc::INVALID, "invalid"}, 55314564Sdim {0x006200000000ULL, 0x008000000000ULL, MappingDesc::SHADOW, "shadow-3"}, 56314564Sdim {0x008000000000ULL, 0x008200000000ULL, MappingDesc::SHADOW, "shadow-1"}, 57314564Sdim {0x008200000000ULL, 0x00a000000000ULL, MappingDesc::ORIGIN, "origin-3"}, 58314564Sdim {0x00a000000000ULL, 0x00a200000000ULL, MappingDesc::ORIGIN, "origin-1"}, 59314564Sdim {0x00a200000000ULL, 0x00c000000000ULL, MappingDesc::APP, "app-2"}, 60314564Sdim {0x00c000000000ULL, 0x00e200000000ULL, MappingDesc::INVALID, "invalid"}, 61314564Sdim {0x00e200000000ULL, 0x00ffffffffffULL, MappingDesc::APP, "app-3"}}; 62280031Sdim 63314564Sdim#define MEM_TO_SHADOW(mem) (((uptr)(mem)) ^ 0x8000000000ULL) 64314564Sdim#define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x2000000000ULL) 65280031Sdim 66296417Sdim#elif SANITIZER_LINUX && defined(__aarch64__) 67296417Sdim 68314564Sdim// The mapping describes both 39-bits, 42-bits, and 48-bits VMA. AArch64 69314564Sdim// maps: 70314564Sdim// - 0x0000000000000-0x0000010000000: 39/42/48-bits program own segments 71314564Sdim// - 0x0005500000000-0x0005600000000: 39-bits PIE program segments 72314564Sdim// - 0x0007f80000000-0x0007fffffffff: 39-bits libraries segments 73314564Sdim// - 0x002aa00000000-0x002ab00000000: 42-bits PIE program segments 74314564Sdim// - 0x003ff00000000-0x003ffffffffff: 42-bits libraries segments 75314564Sdim// - 0x0aaaaa0000000-0x0aaab00000000: 48-bits PIE program segments 76314564Sdim// - 0xffff000000000-0x1000000000000: 48-bits libraries segments 77296417Sdim// It is fragmented in multiples segments to increase the memory available 78296417Sdim// on 42-bits (12.21% of total VMA available for 42-bits and 13.28 for 79314564Sdim// 39 bits). The 48-bits segments only cover the usual PIE/default segments 80314564Sdim// plus some more segments (262144GB total, 0.39% total VMA). 81296417Sdimconst MappingDesc kMemoryLayout[] = { 82296417Sdim {0x00000000000ULL, 0x01000000000ULL, MappingDesc::INVALID, "invalid"}, 83296417Sdim {0x01000000000ULL, 0x02000000000ULL, MappingDesc::SHADOW, "shadow-2"}, 84296417Sdim {0x02000000000ULL, 0x03000000000ULL, MappingDesc::ORIGIN, "origin-2"}, 85296417Sdim {0x03000000000ULL, 0x04000000000ULL, MappingDesc::SHADOW, "shadow-1"}, 86296417Sdim {0x04000000000ULL, 0x05000000000ULL, MappingDesc::ORIGIN, "origin-1"}, 87296417Sdim {0x05000000000ULL, 0x06000000000ULL, MappingDesc::APP, "app-1"}, 88296417Sdim {0x06000000000ULL, 0x07000000000ULL, MappingDesc::INVALID, "invalid"}, 89296417Sdim {0x07000000000ULL, 0x08000000000ULL, MappingDesc::APP, "app-2"}, 90296417Sdim {0x08000000000ULL, 0x09000000000ULL, MappingDesc::INVALID, "invalid"}, 91296417Sdim // The mappings below are used only for 42-bits VMA. 92296417Sdim {0x09000000000ULL, 0x0A000000000ULL, MappingDesc::SHADOW, "shadow-3"}, 93296417Sdim {0x0A000000000ULL, 0x0B000000000ULL, MappingDesc::ORIGIN, "origin-3"}, 94296417Sdim {0x0B000000000ULL, 0x0F000000000ULL, MappingDesc::INVALID, "invalid"}, 95296417Sdim {0x0F000000000ULL, 0x10000000000ULL, MappingDesc::APP, "app-3"}, 96296417Sdim {0x10000000000ULL, 0x11000000000ULL, MappingDesc::INVALID, "invalid"}, 97296417Sdim {0x11000000000ULL, 0x12000000000ULL, MappingDesc::APP, "app-4"}, 98296417Sdim {0x12000000000ULL, 0x17000000000ULL, MappingDesc::INVALID, "invalid"}, 99296417Sdim {0x17000000000ULL, 0x18000000000ULL, MappingDesc::SHADOW, "shadow-4"}, 100296417Sdim {0x18000000000ULL, 0x19000000000ULL, MappingDesc::ORIGIN, "origin-4"}, 101296417Sdim {0x19000000000ULL, 0x20000000000ULL, MappingDesc::INVALID, "invalid"}, 102296417Sdim {0x20000000000ULL, 0x21000000000ULL, MappingDesc::APP, "app-5"}, 103296417Sdim {0x21000000000ULL, 0x26000000000ULL, MappingDesc::INVALID, "invalid"}, 104296417Sdim {0x26000000000ULL, 0x27000000000ULL, MappingDesc::SHADOW, "shadow-5"}, 105296417Sdim {0x27000000000ULL, 0x28000000000ULL, MappingDesc::ORIGIN, "origin-5"}, 106296417Sdim {0x28000000000ULL, 0x29000000000ULL, MappingDesc::SHADOW, "shadow-7"}, 107296417Sdim {0x29000000000ULL, 0x2A000000000ULL, MappingDesc::ORIGIN, "origin-7"}, 108296417Sdim {0x2A000000000ULL, 0x2B000000000ULL, MappingDesc::APP, "app-6"}, 109296417Sdim {0x2B000000000ULL, 0x2C000000000ULL, MappingDesc::INVALID, "invalid"}, 110296417Sdim {0x2C000000000ULL, 0x2D000000000ULL, MappingDesc::SHADOW, "shadow-6"}, 111296417Sdim {0x2D000000000ULL, 0x2E000000000ULL, MappingDesc::ORIGIN, "origin-6"}, 112296417Sdim {0x2E000000000ULL, 0x2F000000000ULL, MappingDesc::APP, "app-7"}, 113296417Sdim {0x2F000000000ULL, 0x39000000000ULL, MappingDesc::INVALID, "invalid"}, 114296417Sdim {0x39000000000ULL, 0x3A000000000ULL, MappingDesc::SHADOW, "shadow-9"}, 115296417Sdim {0x3A000000000ULL, 0x3B000000000ULL, MappingDesc::ORIGIN, "origin-9"}, 116296417Sdim {0x3B000000000ULL, 0x3C000000000ULL, MappingDesc::APP, "app-8"}, 117296417Sdim {0x3C000000000ULL, 0x3D000000000ULL, MappingDesc::INVALID, "invalid"}, 118296417Sdim {0x3D000000000ULL, 0x3E000000000ULL, MappingDesc::SHADOW, "shadow-8"}, 119296417Sdim {0x3E000000000ULL, 0x3F000000000ULL, MappingDesc::ORIGIN, "origin-8"}, 120296417Sdim {0x3F000000000ULL, 0x40000000000ULL, MappingDesc::APP, "app-9"}, 121314564Sdim // The mappings below are used only for 48-bits VMA. 122314564Sdim // TODO(unknown): 48-bit mapping ony covers the usual PIE, non-PIE 123314564Sdim // segments and some more segments totalizing 262144GB of VMA (which cover 124314564Sdim // only 0.32% of all 48-bit VMA). Memory avaliability can be increase by 125314564Sdim // adding multiple application segments like 39 and 42 mapping. 126314564Sdim {0x0040000000000ULL, 0x0041000000000ULL, MappingDesc::INVALID, "invalid"}, 127314564Sdim {0x0041000000000ULL, 0x0042000000000ULL, MappingDesc::APP, "app-10"}, 128314564Sdim {0x0042000000000ULL, 0x0047000000000ULL, MappingDesc::INVALID, "invalid"}, 129314564Sdim {0x0047000000000ULL, 0x0048000000000ULL, MappingDesc::SHADOW, "shadow-10"}, 130314564Sdim {0x0048000000000ULL, 0x0049000000000ULL, MappingDesc::ORIGIN, "origin-10"}, 131314564Sdim {0x0049000000000ULL, 0x0050000000000ULL, MappingDesc::INVALID, "invalid"}, 132314564Sdim {0x0050000000000ULL, 0x0051000000000ULL, MappingDesc::APP, "app-11"}, 133314564Sdim {0x0051000000000ULL, 0x0056000000000ULL, MappingDesc::INVALID, "invalid"}, 134314564Sdim {0x0056000000000ULL, 0x0057000000000ULL, MappingDesc::SHADOW, "shadow-11"}, 135314564Sdim {0x0057000000000ULL, 0x0058000000000ULL, MappingDesc::ORIGIN, "origin-11"}, 136314564Sdim {0x0058000000000ULL, 0x0059000000000ULL, MappingDesc::APP, "app-12"}, 137314564Sdim {0x0059000000000ULL, 0x005E000000000ULL, MappingDesc::INVALID, "invalid"}, 138314564Sdim {0x005E000000000ULL, 0x005F000000000ULL, MappingDesc::SHADOW, "shadow-12"}, 139314564Sdim {0x005F000000000ULL, 0x0060000000000ULL, MappingDesc::ORIGIN, "origin-12"}, 140314564Sdim {0x0060000000000ULL, 0x0061000000000ULL, MappingDesc::INVALID, "invalid"}, 141314564Sdim {0x0061000000000ULL, 0x0062000000000ULL, MappingDesc::APP, "app-13"}, 142314564Sdim {0x0062000000000ULL, 0x0067000000000ULL, MappingDesc::INVALID, "invalid"}, 143314564Sdim {0x0067000000000ULL, 0x0068000000000ULL, MappingDesc::SHADOW, "shadow-13"}, 144314564Sdim {0x0068000000000ULL, 0x0069000000000ULL, MappingDesc::ORIGIN, "origin-13"}, 145314564Sdim {0x0069000000000ULL, 0x0AAAAA0000000ULL, MappingDesc::INVALID, "invalid"}, 146314564Sdim {0x0AAAAA0000000ULL, 0x0AAAB00000000ULL, MappingDesc::APP, "app-14"}, 147314564Sdim {0x0AAAB00000000ULL, 0x0AACAA0000000ULL, MappingDesc::INVALID, "invalid"}, 148314564Sdim {0x0AACAA0000000ULL, 0x0AACB00000000ULL, MappingDesc::SHADOW, "shadow-14"}, 149314564Sdim {0x0AACB00000000ULL, 0x0AADAA0000000ULL, MappingDesc::INVALID, "invalid"}, 150314564Sdim {0x0AADAA0000000ULL, 0x0AADB00000000ULL, MappingDesc::ORIGIN, "origin-14"}, 151314564Sdim {0x0AADB00000000ULL, 0x0FF9F00000000ULL, MappingDesc::INVALID, "invalid"}, 152314564Sdim {0x0FF9F00000000ULL, 0x0FFA000000000ULL, MappingDesc::SHADOW, "shadow-15"}, 153314564Sdim {0x0FFA000000000ULL, 0x0FFAF00000000ULL, MappingDesc::INVALID, "invalid"}, 154314564Sdim {0x0FFAF00000000ULL, 0x0FFB000000000ULL, MappingDesc::ORIGIN, "origin-15"}, 155314564Sdim {0x0FFB000000000ULL, 0x0FFFF00000000ULL, MappingDesc::INVALID, "invalid"}, 156314564Sdim {0x0FFFF00000000ULL, 0x1000000000000ULL, MappingDesc::APP, "app-15"}, 157296417Sdim}; 158296417Sdim# define MEM_TO_SHADOW(mem) ((uptr)mem ^ 0x6000000000ULL) 159296417Sdim# define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x1000000000ULL) 160296417Sdim 161309124Sdim#elif SANITIZER_LINUX && SANITIZER_PPC64 162288943Sdimconst MappingDesc kMemoryLayout[] = { 163327952Sdim {0x000000000000ULL, 0x000200000000ULL, MappingDesc::APP, "low memory"}, 164327952Sdim {0x000200000000ULL, 0x080000000000ULL, MappingDesc::INVALID, "invalid"}, 165327952Sdim {0x080000000000ULL, 0x180200000000ULL, MappingDesc::SHADOW, "shadow"}, 166327952Sdim {0x180200000000ULL, 0x1C0000000000ULL, MappingDesc::INVALID, "invalid"}, 167327952Sdim {0x1C0000000000ULL, 0x2C0200000000ULL, MappingDesc::ORIGIN, "origin"}, 168327952Sdim {0x2C0200000000ULL, 0x300000000000ULL, MappingDesc::INVALID, "invalid"}, 169327952Sdim {0x300000000000ULL, 0x800000000000ULL, MappingDesc::APP, "high memory"}}; 170288943Sdim 171327952Sdim// Various kernels use different low end ranges but we can combine them into one 172327952Sdim// big range. They also use different high end ranges but we can map them all to 173327952Sdim// one range. 174288943Sdim// Maps low and high app ranges to contiguous space with zero base: 175327952Sdim// Low: 0000 0000 0000 - 0001 ffff ffff -> 1000 0000 0000 - 1001 ffff ffff 176288943Sdim// High: 3000 0000 0000 - 3fff ffff ffff -> 0000 0000 0000 - 0fff ffff ffff 177327952Sdim// High: 4000 0000 0000 - 4fff ffff ffff -> 0000 0000 0000 - 0fff ffff ffff 178327952Sdim// High: 7000 0000 0000 - 7fff ffff ffff -> 0000 0000 0000 - 0fff ffff ffff 179288943Sdim#define LINEARIZE_MEM(mem) \ 180327952Sdim (((uptr)(mem) & ~0xE00000000000ULL) ^ 0x100000000000ULL) 181288943Sdim#define MEM_TO_SHADOW(mem) (LINEARIZE_MEM((mem)) + 0x080000000000ULL) 182288943Sdim#define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x140000000000ULL) 183288943Sdim 184276789Sdim#elif SANITIZER_FREEBSD && SANITIZER_WORDSIZE == 64 185280031Sdim 186280031Sdim// Low memory: main binary, MAP_32BIT mappings and modules 187280031Sdim// High memory: heap, modules and main thread stack 188280031Sdimconst MappingDesc kMemoryLayout[] = { 189280031Sdim {0x000000000000ULL, 0x010000000000ULL, MappingDesc::APP, "low memory"}, 190280031Sdim {0x010000000000ULL, 0x100000000000ULL, MappingDesc::INVALID, "invalid"}, 191280031Sdim {0x100000000000ULL, 0x310000000000ULL, MappingDesc::SHADOW, "shadow"}, 192280031Sdim {0x310000000000ULL, 0x380000000000ULL, MappingDesc::INVALID, "invalid"}, 193280031Sdim {0x380000000000ULL, 0x590000000000ULL, MappingDesc::ORIGIN, "origin"}, 194280031Sdim {0x590000000000ULL, 0x600000000000ULL, MappingDesc::INVALID, "invalid"}, 195280031Sdim {0x600000000000ULL, 0x800000000000ULL, MappingDesc::APP, "high memory"}}; 196280031Sdim 197276789Sdim// Maps low and high app ranges to contiguous space with zero base: 198276789Sdim// Low: 0000 0000 0000 - 00ff ffff ffff -> 2000 0000 0000 - 20ff ffff ffff 199276789Sdim// High: 6000 0000 0000 - 7fff ffff ffff -> 0000 0000 0000 - 1fff ffff ffff 200280031Sdim#define LINEARIZE_MEM(mem) \ 201280031Sdim (((uptr)(mem) & ~0xc00000000000ULL) ^ 0x200000000000ULL) 202280031Sdim#define MEM_TO_SHADOW(mem) (LINEARIZE_MEM((mem)) + 0x100000000000ULL) 203280031Sdim#define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x280000000000) 204280031Sdim 205327952Sdim#elif SANITIZER_NETBSD || (SANITIZER_LINUX && SANITIZER_WORDSIZE == 64) 206280031Sdim 207296417Sdim#ifdef MSAN_LINUX_X86_64_OLD_MAPPING 208280031Sdim// Requries PIE binary and ASLR enabled. 209280031Sdim// Main thread stack and DSOs at 0x7f0000000000 (sometimes 0x7e0000000000). 210280031Sdim// Heap at 0x600000000000. 211280031Sdimconst MappingDesc kMemoryLayout[] = { 212280031Sdim {0x000000000000ULL, 0x200000000000ULL, MappingDesc::INVALID, "invalid"}, 213280031Sdim {0x200000000000ULL, 0x400000000000ULL, MappingDesc::SHADOW, "shadow"}, 214280031Sdim {0x400000000000ULL, 0x600000000000ULL, MappingDesc::ORIGIN, "origin"}, 215280031Sdim {0x600000000000ULL, 0x800000000000ULL, MappingDesc::APP, "app"}}; 216280031Sdim 217280031Sdim#define MEM_TO_SHADOW(mem) (((uptr)(mem)) & ~0x400000000000ULL) 218280031Sdim#define SHADOW_TO_ORIGIN(mem) (((uptr)(mem)) + 0x200000000000ULL) 219296417Sdim#else // MSAN_LINUX_X86_64_OLD_MAPPING 220296417Sdim// All of the following configurations are supported. 221296417Sdim// ASLR disabled: main executable and DSOs at 0x555550000000 222296417Sdim// PIE and ASLR: main executable and DSOs at 0x7f0000000000 223296417Sdim// non-PIE: main executable below 0x100000000, DSOs at 0x7f0000000000 224296417Sdim// Heap at 0x700000000000. 225296417Sdimconst MappingDesc kMemoryLayout[] = { 226296417Sdim {0x000000000000ULL, 0x010000000000ULL, MappingDesc::APP, "app-1"}, 227296417Sdim {0x010000000000ULL, 0x100000000000ULL, MappingDesc::SHADOW, "shadow-2"}, 228296417Sdim {0x100000000000ULL, 0x110000000000ULL, MappingDesc::INVALID, "invalid"}, 229296417Sdim {0x110000000000ULL, 0x200000000000ULL, MappingDesc::ORIGIN, "origin-2"}, 230296417Sdim {0x200000000000ULL, 0x300000000000ULL, MappingDesc::SHADOW, "shadow-3"}, 231296417Sdim {0x300000000000ULL, 0x400000000000ULL, MappingDesc::ORIGIN, "origin-3"}, 232296417Sdim {0x400000000000ULL, 0x500000000000ULL, MappingDesc::INVALID, "invalid"}, 233296417Sdim {0x500000000000ULL, 0x510000000000ULL, MappingDesc::SHADOW, "shadow-1"}, 234296417Sdim {0x510000000000ULL, 0x600000000000ULL, MappingDesc::APP, "app-2"}, 235296417Sdim {0x600000000000ULL, 0x610000000000ULL, MappingDesc::ORIGIN, "origin-1"}, 236296417Sdim {0x610000000000ULL, 0x700000000000ULL, MappingDesc::INVALID, "invalid"}, 237296417Sdim {0x700000000000ULL, 0x800000000000ULL, MappingDesc::APP, "app-3"}}; 238296417Sdim#define MEM_TO_SHADOW(mem) (((uptr)(mem)) ^ 0x500000000000ULL) 239296417Sdim#define SHADOW_TO_ORIGIN(mem) (((uptr)(mem)) + 0x100000000000ULL) 240296417Sdim#endif // MSAN_LINUX_X86_64_OLD_MAPPING 241280031Sdim 242276789Sdim#else 243276789Sdim#error "Unsupported platform" 244276789Sdim#endif 245276789Sdim 246280031Sdimconst uptr kMemoryLayoutSize = sizeof(kMemoryLayout) / sizeof(kMemoryLayout[0]); 247276789Sdim 248276789Sdim#define MEM_TO_ORIGIN(mem) (SHADOW_TO_ORIGIN(MEM_TO_SHADOW((mem)))) 249276789Sdim 250280031Sdim#ifndef __clang__ 251280031Sdim__attribute__((optimize("unroll-loops"))) 252280031Sdim#endif 253280031Sdiminline bool addr_is_type(uptr addr, MappingDesc::Type mapping_type) { 254280031Sdim// It is critical for performance that this loop is unrolled (because then it is 255280031Sdim// simplified into just a few constant comparisons). 256280031Sdim#ifdef __clang__ 257280031Sdim#pragma unroll 258280031Sdim#endif 259280031Sdim for (unsigned i = 0; i < kMemoryLayoutSize; ++i) 260280031Sdim if (kMemoryLayout[i].type == mapping_type && 261280031Sdim addr >= kMemoryLayout[i].start && addr < kMemoryLayout[i].end) 262280031Sdim return true; 263280031Sdim return false; 264280031Sdim} 265276789Sdim 266280031Sdim#define MEM_IS_APP(mem) addr_is_type((uptr)(mem), MappingDesc::APP) 267280031Sdim#define MEM_IS_SHADOW(mem) addr_is_type((uptr)(mem), MappingDesc::SHADOW) 268280031Sdim#define MEM_IS_ORIGIN(mem) addr_is_type((uptr)(mem), MappingDesc::ORIGIN) 269245614Sandrew 270360784Sdim// These constants must be kept in sync with the ones in MemorySanitizer.cpp. 271276789Sdimconst int kMsanParamTlsSize = 800; 272276789Sdimconst int kMsanRetvalTlsSize = 800; 273276789Sdim 274245614Sandrewnamespace __msan { 275245614Sandrewextern int msan_inited; 276245614Sandrewextern bool msan_init_is_running; 277245614Sandrewextern int msan_report_count; 278245614Sandrew 279245614Sandrewbool ProtectRange(uptr beg, uptr end); 280288943Sdimbool InitShadow(bool init_origins); 281245614Sandrewchar *GetProcSelfMaps(); 282245614Sandrewvoid InitializeInterceptors(); 283245614Sandrew 284296417Sdimvoid MsanAllocatorInit(); 285274201Sdimvoid MsanAllocatorThreadFinish(); 286274201Sdimvoid MsanDeallocate(StackTrace *stack, void *ptr); 287321369Sdim 288321369Sdimvoid *msan_malloc(uptr size, StackTrace *stack); 289321369Sdimvoid *msan_calloc(uptr nmemb, uptr size, StackTrace *stack); 290321369Sdimvoid *msan_realloc(void *ptr, uptr size, StackTrace *stack); 291353358Sdimvoid *msan_reallocarray(void *ptr, uptr nmemb, uptr size, StackTrace *stack); 292321369Sdimvoid *msan_valloc(uptr size, StackTrace *stack); 293321369Sdimvoid *msan_pvalloc(uptr size, StackTrace *stack); 294321369Sdimvoid *msan_aligned_alloc(uptr alignment, uptr size, StackTrace *stack); 295321369Sdimvoid *msan_memalign(uptr alignment, uptr size, StackTrace *stack); 296321369Sdimint msan_posix_memalign(void **memptr, uptr alignment, uptr size, 297321369Sdim StackTrace *stack); 298321369Sdim 299245614Sandrewvoid InstallTrapHandler(); 300245614Sandrewvoid InstallAtExitHandler(); 301245614Sandrew 302276789Sdimconst char *GetStackOriginDescr(u32 id, uptr *pc); 303274201Sdim 304251034Sedvoid EnterSymbolizer(); 305251034Sedvoid ExitSymbolizer(); 306251034Sedbool IsInSymbolizer(); 307251034Sed 308251034Sedstruct SymbolizerScope { 309251034Sed SymbolizerScope() { EnterSymbolizer(); } 310251034Sed ~SymbolizerScope() { ExitSymbolizer(); } 311251034Sed}; 312251034Sed 313245614Sandrewvoid PrintWarning(uptr pc, uptr bp); 314245614Sandrewvoid PrintWarningWithOrigin(uptr pc, uptr bp, u32 origin); 315245614Sandrew 316274201Sdim// Unpoison first n function arguments. 317274201Sdimvoid UnpoisonParam(uptr n); 318274201Sdimvoid UnpoisonThreadLocalState(); 319251034Sed 320276789Sdim// Returns a "chained" origin id, pointing to the given stack trace followed by 321276789Sdim// the previous origin id. 322276789Sdimu32 ChainOrigin(u32 id, StackTrace *stack); 323276789Sdim 324280031Sdimconst int STACK_TRACE_TAG_POISON = StackTrace::TAG_CUSTOM + 1; 325280031Sdim 326327952Sdim#define GET_MALLOC_STACK_TRACE \ 327327952Sdim BufferedStackTrace stack; \ 328327952Sdim if (__msan_get_track_origins() && msan_inited) \ 329353358Sdim stack.Unwind(StackTrace::GetCurrentPc(), GET_CURRENT_FRAME(), \ 330353358Sdim nullptr, common_flags()->fast_unwind_on_malloc, \ 331353358Sdim common_flags()->malloc_context_size) 332276789Sdim 333314564Sdim// For platforms which support slow unwinder only, we restrict the store context 334314564Sdim// size to 1, basically only storing the current pc. We do this because the slow 335314564Sdim// unwinder which is based on libunwind is not async signal safe and causes 336314564Sdim// random freezes in forking applications as well as in signal handlers. 337353358Sdim#define GET_STORE_STACK_TRACE_PC_BP(pc, bp) \ 338353358Sdim BufferedStackTrace stack; \ 339353358Sdim if (__msan_get_track_origins() > 1 && msan_inited) { \ 340353358Sdim int size = flags()->store_context_size; \ 341353358Sdim if (!SANITIZER_CAN_FAST_UNWIND) \ 342353358Sdim size = Min(size, 1); \ 343353358Sdim stack.Unwind(pc, bp, nullptr, common_flags()->fast_unwind_on_malloc, size);\ 344314564Sdim } 345276789Sdim 346341825Sdim#define GET_STORE_STACK_TRACE \ 347341825Sdim GET_STORE_STACK_TRACE_PC_BP(StackTrace::GetCurrentPc(), GET_CURRENT_FRAME()) 348341825Sdim 349360784Sdim#define GET_FATAL_STACK_TRACE_PC_BP(pc, bp) \ 350360784Sdim BufferedStackTrace stack; \ 351360784Sdim if (msan_inited) { \ 352360784Sdim stack.Unwind(pc, bp, nullptr, common_flags()->fast_unwind_on_fatal); \ 353360784Sdim } 354276789Sdim 355341825Sdim#define GET_FATAL_STACK_TRACE_HERE \ 356341825Sdim GET_FATAL_STACK_TRACE_PC_BP(StackTrace::GetCurrentPc(), GET_CURRENT_FRAME()) 357276789Sdim 358341825Sdim#define PRINT_CURRENT_STACK_CHECK() \ 359341825Sdim { \ 360341825Sdim GET_FATAL_STACK_TRACE_HERE; \ 361341825Sdim stack.Print(); \ 362341825Sdim } 363341825Sdim 364274201Sdimclass ScopedThreadLocalStateBackup { 365274201Sdim public: 366274201Sdim ScopedThreadLocalStateBackup() { Backup(); } 367274201Sdim ~ScopedThreadLocalStateBackup() { Restore(); } 368274201Sdim void Backup(); 369274201Sdim void Restore(); 370274201Sdim private: 371274201Sdim u64 va_arg_overflow_size_tls; 372274201Sdim}; 373276789Sdim 374276789Sdimvoid MsanTSDInit(void (*destructor)(void *tsd)); 375276789Sdimvoid *MsanTSDGet(); 376276789Sdimvoid MsanTSDSet(void *tsd); 377276789Sdimvoid MsanTSDDtor(void *tsd); 378276789Sdim 379245614Sandrew} // namespace __msan 380245614Sandrew 381309124Sdim#define MSAN_MALLOC_HOOK(ptr, size) \ 382309124Sdim do { \ 383309124Sdim if (&__sanitizer_malloc_hook) { \ 384309124Sdim UnpoisonParam(2); \ 385309124Sdim __sanitizer_malloc_hook(ptr, size); \ 386309124Sdim } \ 387309124Sdim RunMallocHooks(ptr, size); \ 388309124Sdim } while (false) 389309124Sdim#define MSAN_FREE_HOOK(ptr) \ 390309124Sdim do { \ 391309124Sdim if (&__sanitizer_free_hook) { \ 392309124Sdim UnpoisonParam(1); \ 393309124Sdim __sanitizer_free_hook(ptr); \ 394309124Sdim } \ 395309124Sdim RunFreeHooks(ptr); \ 396309124Sdim } while (false) 397274201Sdim 398245614Sandrew#endif // MSAN_H 399