xref: /openbsd-src/gnu/llvm/compiler-rt/lib/msan/msan.h (revision 810390e339a5425391477d5d41c78d7cab2424ac)
13cab2bb3Spatrick //===-- msan.h --------------------------------------------------*- C++ -*-===//
23cab2bb3Spatrick //
33cab2bb3Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
43cab2bb3Spatrick // See https://llvm.org/LICENSE.txt for license information.
53cab2bb3Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
63cab2bb3Spatrick //
73cab2bb3Spatrick //===----------------------------------------------------------------------===//
83cab2bb3Spatrick //
93cab2bb3Spatrick // This file is a part of MemorySanitizer.
103cab2bb3Spatrick //
113cab2bb3Spatrick // Private MSan header.
123cab2bb3Spatrick //===----------------------------------------------------------------------===//
133cab2bb3Spatrick 
143cab2bb3Spatrick #ifndef MSAN_H
153cab2bb3Spatrick #define MSAN_H
163cab2bb3Spatrick 
173cab2bb3Spatrick #include "sanitizer_common/sanitizer_flags.h"
183cab2bb3Spatrick #include "sanitizer_common/sanitizer_internal_defs.h"
193cab2bb3Spatrick #include "sanitizer_common/sanitizer_stacktrace.h"
203cab2bb3Spatrick #include "msan_interface_internal.h"
213cab2bb3Spatrick #include "msan_flags.h"
223cab2bb3Spatrick #include "ubsan/ubsan_platform.h"
233cab2bb3Spatrick 
243cab2bb3Spatrick #ifndef MSAN_REPLACE_OPERATORS_NEW_AND_DELETE
253cab2bb3Spatrick # define MSAN_REPLACE_OPERATORS_NEW_AND_DELETE 1
263cab2bb3Spatrick #endif
273cab2bb3Spatrick 
283cab2bb3Spatrick #ifndef MSAN_CONTAINS_UBSAN
293cab2bb3Spatrick # define MSAN_CONTAINS_UBSAN CAN_SANITIZE_UB
303cab2bb3Spatrick #endif
313cab2bb3Spatrick 
323cab2bb3Spatrick struct MappingDesc {
333cab2bb3Spatrick   uptr start;
343cab2bb3Spatrick   uptr end;
353cab2bb3Spatrick   enum Type {
363cab2bb3Spatrick     INVALID, APP, SHADOW, ORIGIN
373cab2bb3Spatrick   } type;
383cab2bb3Spatrick   const char *name;
393cab2bb3Spatrick };
403cab2bb3Spatrick 
413cab2bb3Spatrick 
423cab2bb3Spatrick #if SANITIZER_LINUX && defined(__mips64)
433cab2bb3Spatrick 
443cab2bb3Spatrick // MIPS64 maps:
453cab2bb3Spatrick // - 0x0000000000-0x0200000000: Program own segments
463cab2bb3Spatrick // - 0xa200000000-0xc000000000: PIE program segments
473cab2bb3Spatrick // - 0xe200000000-0xffffffffff: libraries segments.
483cab2bb3Spatrick const MappingDesc kMemoryLayout[] = {
493cab2bb3Spatrick     {0x000000000000ULL, 0x000200000000ULL, MappingDesc::APP, "app-1"},
503cab2bb3Spatrick     {0x000200000000ULL, 0x002200000000ULL, MappingDesc::INVALID, "invalid"},
513cab2bb3Spatrick     {0x002200000000ULL, 0x004000000000ULL, MappingDesc::SHADOW, "shadow-2"},
523cab2bb3Spatrick     {0x004000000000ULL, 0x004200000000ULL, MappingDesc::INVALID, "invalid"},
533cab2bb3Spatrick     {0x004200000000ULL, 0x006000000000ULL, MappingDesc::ORIGIN, "origin-2"},
543cab2bb3Spatrick     {0x006000000000ULL, 0x006200000000ULL, MappingDesc::INVALID, "invalid"},
553cab2bb3Spatrick     {0x006200000000ULL, 0x008000000000ULL, MappingDesc::SHADOW, "shadow-3"},
563cab2bb3Spatrick     {0x008000000000ULL, 0x008200000000ULL, MappingDesc::SHADOW, "shadow-1"},
573cab2bb3Spatrick     {0x008200000000ULL, 0x00a000000000ULL, MappingDesc::ORIGIN, "origin-3"},
583cab2bb3Spatrick     {0x00a000000000ULL, 0x00a200000000ULL, MappingDesc::ORIGIN, "origin-1"},
593cab2bb3Spatrick     {0x00a200000000ULL, 0x00c000000000ULL, MappingDesc::APP, "app-2"},
603cab2bb3Spatrick     {0x00c000000000ULL, 0x00e200000000ULL, MappingDesc::INVALID, "invalid"},
613cab2bb3Spatrick     {0x00e200000000ULL, 0x00ffffffffffULL, MappingDesc::APP, "app-3"}};
623cab2bb3Spatrick 
633cab2bb3Spatrick #define MEM_TO_SHADOW(mem) (((uptr)(mem)) ^ 0x8000000000ULL)
643cab2bb3Spatrick #define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x2000000000ULL)
653cab2bb3Spatrick 
663cab2bb3Spatrick #elif SANITIZER_LINUX && defined(__aarch64__)
673cab2bb3Spatrick 
68*810390e3Srobert // The mapping assumes 48-bit VMA. AArch64 maps:
69*810390e3Srobert // - 0x0000000000000-0x0100000000000: 39/42/48-bits program own segments
70*810390e3Srobert // - 0x0a00000000000-0x0b00000000000: 48-bits PIE program segments
71*810390e3Srobert //   Ideally, this would extend to 0x0c00000000000 (2^45 bytes - the
72*810390e3Srobert //   maximum ASLR region for 48-bit VMA) but it is too hard to fit in
73*810390e3Srobert //   the larger app/shadow/origin regions.
74*810390e3Srobert // - 0x0e00000000000-0x1000000000000: 48-bits libraries segments
753cab2bb3Spatrick const MappingDesc kMemoryLayout[] = {
76*810390e3Srobert     {0X0000000000000, 0X0100000000000, MappingDesc::APP, "app-10-13"},
77*810390e3Srobert     {0X0100000000000, 0X0200000000000, MappingDesc::SHADOW, "shadow-14"},
78*810390e3Srobert     {0X0200000000000, 0X0300000000000, MappingDesc::INVALID, "invalid"},
79*810390e3Srobert     {0X0300000000000, 0X0400000000000, MappingDesc::ORIGIN, "origin-14"},
80*810390e3Srobert     {0X0400000000000, 0X0600000000000, MappingDesc::SHADOW, "shadow-15"},
81*810390e3Srobert     {0X0600000000000, 0X0800000000000, MappingDesc::ORIGIN, "origin-15"},
82*810390e3Srobert     {0X0800000000000, 0X0A00000000000, MappingDesc::INVALID, "invalid"},
83*810390e3Srobert     {0X0A00000000000, 0X0B00000000000, MappingDesc::APP, "app-14"},
84*810390e3Srobert     {0X0B00000000000, 0X0C00000000000, MappingDesc::SHADOW, "shadow-10-13"},
85*810390e3Srobert     {0X0C00000000000, 0X0D00000000000, MappingDesc::INVALID, "invalid"},
86*810390e3Srobert     {0X0D00000000000, 0X0E00000000000, MappingDesc::ORIGIN, "origin-10-13"},
87*810390e3Srobert     {0X0E00000000000, 0X1000000000000, MappingDesc::APP, "app-15"},
883cab2bb3Spatrick };
89*810390e3Srobert # define MEM_TO_SHADOW(mem) ((uptr)mem ^ 0xB00000000000ULL)
90*810390e3Srobert # define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x200000000000ULL)
913cab2bb3Spatrick 
923cab2bb3Spatrick #elif SANITIZER_LINUX && SANITIZER_PPC64
933cab2bb3Spatrick const MappingDesc kMemoryLayout[] = {
943cab2bb3Spatrick     {0x000000000000ULL, 0x000200000000ULL, MappingDesc::APP, "low memory"},
953cab2bb3Spatrick     {0x000200000000ULL, 0x080000000000ULL, MappingDesc::INVALID, "invalid"},
963cab2bb3Spatrick     {0x080000000000ULL, 0x180200000000ULL, MappingDesc::SHADOW, "shadow"},
973cab2bb3Spatrick     {0x180200000000ULL, 0x1C0000000000ULL, MappingDesc::INVALID, "invalid"},
983cab2bb3Spatrick     {0x1C0000000000ULL, 0x2C0200000000ULL, MappingDesc::ORIGIN, "origin"},
993cab2bb3Spatrick     {0x2C0200000000ULL, 0x300000000000ULL, MappingDesc::INVALID, "invalid"},
1003cab2bb3Spatrick     {0x300000000000ULL, 0x800000000000ULL, MappingDesc::APP, "high memory"}};
1013cab2bb3Spatrick 
1023cab2bb3Spatrick // Various kernels use different low end ranges but we can combine them into one
1033cab2bb3Spatrick // big range. They also use different high end ranges but we can map them all to
1043cab2bb3Spatrick // one range.
1053cab2bb3Spatrick // Maps low and high app ranges to contiguous space with zero base:
1063cab2bb3Spatrick //   Low:  0000 0000 0000 - 0001 ffff ffff  ->  1000 0000 0000 - 1001 ffff ffff
1073cab2bb3Spatrick //   High: 3000 0000 0000 - 3fff ffff ffff  ->  0000 0000 0000 - 0fff ffff ffff
1083cab2bb3Spatrick //   High: 4000 0000 0000 - 4fff ffff ffff  ->  0000 0000 0000 - 0fff ffff ffff
1093cab2bb3Spatrick //   High: 7000 0000 0000 - 7fff ffff ffff  ->  0000 0000 0000 - 0fff ffff ffff
1103cab2bb3Spatrick #define LINEARIZE_MEM(mem) \
1113cab2bb3Spatrick   (((uptr)(mem) & ~0xE00000000000ULL) ^ 0x100000000000ULL)
1123cab2bb3Spatrick #define MEM_TO_SHADOW(mem) (LINEARIZE_MEM((mem)) + 0x080000000000ULL)
1133cab2bb3Spatrick #define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x140000000000ULL)
1143cab2bb3Spatrick 
1151f9cb04fSpatrick #elif SANITIZER_LINUX && SANITIZER_S390_64
1161f9cb04fSpatrick const MappingDesc kMemoryLayout[] = {
1171f9cb04fSpatrick     {0x000000000000ULL, 0x040000000000ULL, MappingDesc::APP, "low memory"},
1181f9cb04fSpatrick     {0x040000000000ULL, 0x080000000000ULL, MappingDesc::INVALID, "invalid"},
1191f9cb04fSpatrick     {0x080000000000ULL, 0x180000000000ULL, MappingDesc::SHADOW, "shadow"},
1201f9cb04fSpatrick     {0x180000000000ULL, 0x1C0000000000ULL, MappingDesc::INVALID, "invalid"},
1211f9cb04fSpatrick     {0x1C0000000000ULL, 0x2C0000000000ULL, MappingDesc::ORIGIN, "origin"},
1221f9cb04fSpatrick     {0x2C0000000000ULL, 0x440000000000ULL, MappingDesc::INVALID, "invalid"},
1231f9cb04fSpatrick     {0x440000000000ULL, 0x500000000000ULL, MappingDesc::APP, "high memory"}};
1241f9cb04fSpatrick 
1251f9cb04fSpatrick #define MEM_TO_SHADOW(mem) \
1261f9cb04fSpatrick   ((((uptr)(mem)) & ~0xC00000000000ULL) + 0x080000000000ULL)
1271f9cb04fSpatrick #define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x140000000000ULL)
1281f9cb04fSpatrick 
129*810390e3Srobert #elif SANITIZER_FREEBSD && defined(__aarch64__)
130*810390e3Srobert 
131*810390e3Srobert // Low memory: main binary, MAP_32BIT mappings and modules
132*810390e3Srobert // High memory: heap, modules and main thread stack
133*810390e3Srobert const MappingDesc kMemoryLayout[] = {
134*810390e3Srobert     {0x000000000000ULL, 0x020000000000ULL, MappingDesc::APP, "low memory"},
135*810390e3Srobert     {0x020000000000ULL, 0x200000000000ULL, MappingDesc::INVALID, "invalid"},
136*810390e3Srobert     {0x200000000000ULL, 0x620000000000ULL, MappingDesc::SHADOW, "shadow"},
137*810390e3Srobert     {0x620000000000ULL, 0x700000000000ULL, MappingDesc::INVALID, "invalid"},
138*810390e3Srobert     {0x700000000000ULL, 0xb20000000000ULL, MappingDesc::ORIGIN, "origin"},
139*810390e3Srobert     {0xb20000000000ULL, 0xc00000000000ULL, MappingDesc::INVALID, "invalid"},
140*810390e3Srobert     {0xc00000000000ULL, 0x1000000000000ULL, MappingDesc::APP, "high memory"}};
141*810390e3Srobert 
142*810390e3Srobert // Maps low and high app ranges to contiguous space with zero base:
143*810390e3Srobert //   Low:  0000 0000 0000 - 01ff ffff ffff -> 4000 0000 0000 - 41ff ffff ffff
144*810390e3Srobert //   High: c000 0000 0000 - ffff ffff ffff -> 0000 0000 0000 - 3fff ffff ffff
145*810390e3Srobert #define LINEARIZE_MEM(mem) \
146*810390e3Srobert   (((uptr)(mem) & ~0x1800000000000ULL) ^ 0x400000000000ULL)
147*810390e3Srobert #define MEM_TO_SHADOW(mem) (LINEARIZE_MEM((mem)) + 0x200000000000ULL)
148*810390e3Srobert #define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x500000000000)
149*810390e3Srobert 
1503cab2bb3Spatrick #elif SANITIZER_FREEBSD && SANITIZER_WORDSIZE == 64
1513cab2bb3Spatrick 
1523cab2bb3Spatrick // Low memory: main binary, MAP_32BIT mappings and modules
1533cab2bb3Spatrick // High memory: heap, modules and main thread stack
1543cab2bb3Spatrick const MappingDesc kMemoryLayout[] = {
1553cab2bb3Spatrick     {0x000000000000ULL, 0x010000000000ULL, MappingDesc::APP, "low memory"},
1563cab2bb3Spatrick     {0x010000000000ULL, 0x100000000000ULL, MappingDesc::INVALID, "invalid"},
1573cab2bb3Spatrick     {0x100000000000ULL, 0x310000000000ULL, MappingDesc::SHADOW, "shadow"},
1583cab2bb3Spatrick     {0x310000000000ULL, 0x380000000000ULL, MappingDesc::INVALID, "invalid"},
1593cab2bb3Spatrick     {0x380000000000ULL, 0x590000000000ULL, MappingDesc::ORIGIN, "origin"},
1603cab2bb3Spatrick     {0x590000000000ULL, 0x600000000000ULL, MappingDesc::INVALID, "invalid"},
1613cab2bb3Spatrick     {0x600000000000ULL, 0x800000000000ULL, MappingDesc::APP, "high memory"}};
1623cab2bb3Spatrick 
1633cab2bb3Spatrick // Maps low and high app ranges to contiguous space with zero base:
1643cab2bb3Spatrick //   Low:  0000 0000 0000 - 00ff ffff ffff  ->  2000 0000 0000 - 20ff ffff ffff
1653cab2bb3Spatrick //   High: 6000 0000 0000 - 7fff ffff ffff  ->  0000 0000 0000 - 1fff ffff ffff
1663cab2bb3Spatrick #define LINEARIZE_MEM(mem) \
1673cab2bb3Spatrick   (((uptr)(mem) & ~0xc00000000000ULL) ^ 0x200000000000ULL)
1683cab2bb3Spatrick #define MEM_TO_SHADOW(mem) (LINEARIZE_MEM((mem)) + 0x100000000000ULL)
1693cab2bb3Spatrick #define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x280000000000)
1703cab2bb3Spatrick 
1713cab2bb3Spatrick #elif SANITIZER_NETBSD || (SANITIZER_LINUX && SANITIZER_WORDSIZE == 64)
1723cab2bb3Spatrick 
1733cab2bb3Spatrick // All of the following configurations are supported.
1743cab2bb3Spatrick // ASLR disabled: main executable and DSOs at 0x555550000000
1753cab2bb3Spatrick // PIE and ASLR: main executable and DSOs at 0x7f0000000000
1763cab2bb3Spatrick // non-PIE: main executable below 0x100000000, DSOs at 0x7f0000000000
1773cab2bb3Spatrick // Heap at 0x700000000000.
1783cab2bb3Spatrick const MappingDesc kMemoryLayout[] = {
1793cab2bb3Spatrick     {0x000000000000ULL, 0x010000000000ULL, MappingDesc::APP, "app-1"},
1803cab2bb3Spatrick     {0x010000000000ULL, 0x100000000000ULL, MappingDesc::SHADOW, "shadow-2"},
1813cab2bb3Spatrick     {0x100000000000ULL, 0x110000000000ULL, MappingDesc::INVALID, "invalid"},
1823cab2bb3Spatrick     {0x110000000000ULL, 0x200000000000ULL, MappingDesc::ORIGIN, "origin-2"},
1833cab2bb3Spatrick     {0x200000000000ULL, 0x300000000000ULL, MappingDesc::SHADOW, "shadow-3"},
1843cab2bb3Spatrick     {0x300000000000ULL, 0x400000000000ULL, MappingDesc::ORIGIN, "origin-3"},
1853cab2bb3Spatrick     {0x400000000000ULL, 0x500000000000ULL, MappingDesc::INVALID, "invalid"},
1863cab2bb3Spatrick     {0x500000000000ULL, 0x510000000000ULL, MappingDesc::SHADOW, "shadow-1"},
1873cab2bb3Spatrick     {0x510000000000ULL, 0x600000000000ULL, MappingDesc::APP, "app-2"},
1883cab2bb3Spatrick     {0x600000000000ULL, 0x610000000000ULL, MappingDesc::ORIGIN, "origin-1"},
1893cab2bb3Spatrick     {0x610000000000ULL, 0x700000000000ULL, MappingDesc::INVALID, "invalid"},
1903cab2bb3Spatrick     {0x700000000000ULL, 0x800000000000ULL, MappingDesc::APP, "app-3"}};
1913cab2bb3Spatrick #define MEM_TO_SHADOW(mem) (((uptr)(mem)) ^ 0x500000000000ULL)
1923cab2bb3Spatrick #define SHADOW_TO_ORIGIN(mem) (((uptr)(mem)) + 0x100000000000ULL)
1933cab2bb3Spatrick 
1943cab2bb3Spatrick #else
1953cab2bb3Spatrick #error "Unsupported platform"
1963cab2bb3Spatrick #endif
1973cab2bb3Spatrick 
1983cab2bb3Spatrick const uptr kMemoryLayoutSize = sizeof(kMemoryLayout) / sizeof(kMemoryLayout[0]);
1993cab2bb3Spatrick 
2003cab2bb3Spatrick #define MEM_TO_ORIGIN(mem) (SHADOW_TO_ORIGIN(MEM_TO_SHADOW((mem))))
2013cab2bb3Spatrick 
2023cab2bb3Spatrick #ifndef __clang__
2033cab2bb3Spatrick __attribute__((optimize("unroll-loops")))
2043cab2bb3Spatrick #endif
addr_is_type(uptr addr,MappingDesc::Type mapping_type)2053cab2bb3Spatrick inline bool addr_is_type(uptr addr, MappingDesc::Type mapping_type) {
2063cab2bb3Spatrick // It is critical for performance that this loop is unrolled (because then it is
2073cab2bb3Spatrick // simplified into just a few constant comparisons).
2083cab2bb3Spatrick #ifdef __clang__
2093cab2bb3Spatrick #pragma unroll
2103cab2bb3Spatrick #endif
2113cab2bb3Spatrick   for (unsigned i = 0; i < kMemoryLayoutSize; ++i)
2123cab2bb3Spatrick     if (kMemoryLayout[i].type == mapping_type &&
2133cab2bb3Spatrick         addr >= kMemoryLayout[i].start && addr < kMemoryLayout[i].end)
2143cab2bb3Spatrick       return true;
2153cab2bb3Spatrick   return false;
2163cab2bb3Spatrick }
2173cab2bb3Spatrick 
2183cab2bb3Spatrick #define MEM_IS_APP(mem) addr_is_type((uptr)(mem), MappingDesc::APP)
2193cab2bb3Spatrick #define MEM_IS_SHADOW(mem) addr_is_type((uptr)(mem), MappingDesc::SHADOW)
2203cab2bb3Spatrick #define MEM_IS_ORIGIN(mem) addr_is_type((uptr)(mem), MappingDesc::ORIGIN)
2213cab2bb3Spatrick 
2223cab2bb3Spatrick // These constants must be kept in sync with the ones in MemorySanitizer.cpp.
2233cab2bb3Spatrick const int kMsanParamTlsSize = 800;
2243cab2bb3Spatrick const int kMsanRetvalTlsSize = 800;
2253cab2bb3Spatrick 
2263cab2bb3Spatrick namespace __msan {
2273cab2bb3Spatrick extern int msan_inited;
2283cab2bb3Spatrick extern bool msan_init_is_running;
2293cab2bb3Spatrick extern int msan_report_count;
2303cab2bb3Spatrick 
2313cab2bb3Spatrick bool ProtectRange(uptr beg, uptr end);
2323cab2bb3Spatrick bool InitShadow(bool init_origins);
2333cab2bb3Spatrick char *GetProcSelfMaps();
2343cab2bb3Spatrick void InitializeInterceptors();
2353cab2bb3Spatrick 
2363cab2bb3Spatrick void MsanAllocatorInit();
2373cab2bb3Spatrick void MsanDeallocate(StackTrace *stack, void *ptr);
2383cab2bb3Spatrick 
2393cab2bb3Spatrick void *msan_malloc(uptr size, StackTrace *stack);
2403cab2bb3Spatrick void *msan_calloc(uptr nmemb, uptr size, StackTrace *stack);
2413cab2bb3Spatrick void *msan_realloc(void *ptr, uptr size, StackTrace *stack);
2423cab2bb3Spatrick void *msan_reallocarray(void *ptr, uptr nmemb, uptr size, StackTrace *stack);
2433cab2bb3Spatrick void *msan_valloc(uptr size, StackTrace *stack);
2443cab2bb3Spatrick void *msan_pvalloc(uptr size, StackTrace *stack);
2453cab2bb3Spatrick void *msan_aligned_alloc(uptr alignment, uptr size, StackTrace *stack);
2463cab2bb3Spatrick void *msan_memalign(uptr alignment, uptr size, StackTrace *stack);
2473cab2bb3Spatrick int msan_posix_memalign(void **memptr, uptr alignment, uptr size,
2483cab2bb3Spatrick                         StackTrace *stack);
2493cab2bb3Spatrick 
2503cab2bb3Spatrick void InstallTrapHandler();
2513cab2bb3Spatrick void InstallAtExitHandler();
2523cab2bb3Spatrick 
2533cab2bb3Spatrick const char *GetStackOriginDescr(u32 id, uptr *pc);
2543cab2bb3Spatrick 
255*810390e3Srobert bool IsInSymbolizerOrUnwider();
2563cab2bb3Spatrick 
2573cab2bb3Spatrick void PrintWarning(uptr pc, uptr bp);
2583cab2bb3Spatrick void PrintWarningWithOrigin(uptr pc, uptr bp, u32 origin);
2593cab2bb3Spatrick 
2603cab2bb3Spatrick // Unpoison first n function arguments.
2613cab2bb3Spatrick void UnpoisonParam(uptr n);
2623cab2bb3Spatrick void UnpoisonThreadLocalState();
2633cab2bb3Spatrick 
2643cab2bb3Spatrick // Returns a "chained" origin id, pointing to the given stack trace followed by
2653cab2bb3Spatrick // the previous origin id.
2663cab2bb3Spatrick u32 ChainOrigin(u32 id, StackTrace *stack);
2673cab2bb3Spatrick 
2683cab2bb3Spatrick const int STACK_TRACE_TAG_POISON = StackTrace::TAG_CUSTOM + 1;
269*810390e3Srobert const int STACK_TRACE_TAG_FIELDS = STACK_TRACE_TAG_POISON + 1;
270*810390e3Srobert const int STACK_TRACE_TAG_VPTR = STACK_TRACE_TAG_FIELDS + 1;
2713cab2bb3Spatrick 
2723cab2bb3Spatrick #define GET_MALLOC_STACK_TRACE                                            \
2733cab2bb3Spatrick   BufferedStackTrace stack;                                               \
2743cab2bb3Spatrick   if (__msan_get_track_origins() && msan_inited)                          \
2753cab2bb3Spatrick     stack.Unwind(StackTrace::GetCurrentPc(), GET_CURRENT_FRAME(),         \
2763cab2bb3Spatrick                  nullptr, common_flags()->fast_unwind_on_malloc,          \
2773cab2bb3Spatrick                  common_flags()->malloc_context_size)
2783cab2bb3Spatrick 
2793cab2bb3Spatrick // For platforms which support slow unwinder only, we restrict the store context
2803cab2bb3Spatrick // size to 1, basically only storing the current pc. We do this because the slow
2813cab2bb3Spatrick // unwinder which is based on libunwind is not async signal safe and causes
2823cab2bb3Spatrick // random freezes in forking applications as well as in signal handlers.
2833cab2bb3Spatrick #define GET_STORE_STACK_TRACE_PC_BP(pc, bp)                                    \
2843cab2bb3Spatrick   BufferedStackTrace stack;                                                    \
2853cab2bb3Spatrick   if (__msan_get_track_origins() > 1 && msan_inited) {                         \
2863cab2bb3Spatrick     int size = flags()->store_context_size;                                    \
2873cab2bb3Spatrick     if (!SANITIZER_CAN_FAST_UNWIND)                                            \
2883cab2bb3Spatrick       size = Min(size, 1);                                                     \
2893cab2bb3Spatrick     stack.Unwind(pc, bp, nullptr, common_flags()->fast_unwind_on_malloc, size);\
2903cab2bb3Spatrick   }
2913cab2bb3Spatrick 
2923cab2bb3Spatrick #define GET_STORE_STACK_TRACE \
2933cab2bb3Spatrick   GET_STORE_STACK_TRACE_PC_BP(StackTrace::GetCurrentPc(), GET_CURRENT_FRAME())
2943cab2bb3Spatrick 
2953cab2bb3Spatrick #define GET_FATAL_STACK_TRACE_PC_BP(pc, bp)                              \
2963cab2bb3Spatrick   BufferedStackTrace stack;                                              \
2973cab2bb3Spatrick   if (msan_inited) {                                                     \
2983cab2bb3Spatrick     stack.Unwind(pc, bp, nullptr, common_flags()->fast_unwind_on_fatal); \
2993cab2bb3Spatrick   }
3003cab2bb3Spatrick 
3013cab2bb3Spatrick class ScopedThreadLocalStateBackup {
3023cab2bb3Spatrick  public:
ScopedThreadLocalStateBackup()3033cab2bb3Spatrick   ScopedThreadLocalStateBackup() { Backup(); }
~ScopedThreadLocalStateBackup()3043cab2bb3Spatrick   ~ScopedThreadLocalStateBackup() { Restore(); }
3053cab2bb3Spatrick   void Backup();
3063cab2bb3Spatrick   void Restore();
3073cab2bb3Spatrick  private:
3083cab2bb3Spatrick   u64 va_arg_overflow_size_tls;
3093cab2bb3Spatrick };
3103cab2bb3Spatrick 
3113cab2bb3Spatrick void MsanTSDInit(void (*destructor)(void *tsd));
3123cab2bb3Spatrick void *MsanTSDGet();
3133cab2bb3Spatrick void MsanTSDSet(void *tsd);
3143cab2bb3Spatrick void MsanTSDDtor(void *tsd);
3153cab2bb3Spatrick 
3163cab2bb3Spatrick }  // namespace __msan
3173cab2bb3Spatrick 
3183cab2bb3Spatrick #endif  // MSAN_H
319