1*7c3d14c8STreehugger Robot //===-- msan.h --------------------------------------------------*- C++ -*-===//
2*7c3d14c8STreehugger Robot //
3*7c3d14c8STreehugger Robot // The LLVM Compiler Infrastructure
4*7c3d14c8STreehugger Robot //
5*7c3d14c8STreehugger Robot // This file is distributed under the University of Illinois Open Source
6*7c3d14c8STreehugger Robot // License. See LICENSE.TXT for details.
7*7c3d14c8STreehugger Robot //
8*7c3d14c8STreehugger Robot //===----------------------------------------------------------------------===//
9*7c3d14c8STreehugger Robot //
10*7c3d14c8STreehugger Robot // This file is a part of MemorySanitizer.
11*7c3d14c8STreehugger Robot //
12*7c3d14c8STreehugger Robot // Private MSan header.
13*7c3d14c8STreehugger Robot //===----------------------------------------------------------------------===//
14*7c3d14c8STreehugger Robot
15*7c3d14c8STreehugger Robot #ifndef MSAN_H
16*7c3d14c8STreehugger Robot #define MSAN_H
17*7c3d14c8STreehugger Robot
18*7c3d14c8STreehugger Robot #include "sanitizer_common/sanitizer_flags.h"
19*7c3d14c8STreehugger Robot #include "sanitizer_common/sanitizer_internal_defs.h"
20*7c3d14c8STreehugger Robot #include "sanitizer_common/sanitizer_stacktrace.h"
21*7c3d14c8STreehugger Robot #include "msan_interface_internal.h"
22*7c3d14c8STreehugger Robot #include "msan_flags.h"
23*7c3d14c8STreehugger Robot #include "ubsan/ubsan_platform.h"
24*7c3d14c8STreehugger Robot
25*7c3d14c8STreehugger Robot #ifndef MSAN_REPLACE_OPERATORS_NEW_AND_DELETE
26*7c3d14c8STreehugger Robot # define MSAN_REPLACE_OPERATORS_NEW_AND_DELETE 1
27*7c3d14c8STreehugger Robot #endif
28*7c3d14c8STreehugger Robot
29*7c3d14c8STreehugger Robot #ifndef MSAN_CONTAINS_UBSAN
30*7c3d14c8STreehugger Robot # define MSAN_CONTAINS_UBSAN CAN_SANITIZE_UB
31*7c3d14c8STreehugger Robot #endif
32*7c3d14c8STreehugger Robot
33*7c3d14c8STreehugger Robot struct MappingDesc {
34*7c3d14c8STreehugger Robot uptr start;
35*7c3d14c8STreehugger Robot uptr end;
36*7c3d14c8STreehugger Robot enum Type {
37*7c3d14c8STreehugger Robot INVALID, APP, SHADOW, ORIGIN
38*7c3d14c8STreehugger Robot } type;
39*7c3d14c8STreehugger Robot const char *name;
40*7c3d14c8STreehugger Robot };
41*7c3d14c8STreehugger Robot
42*7c3d14c8STreehugger Robot
43*7c3d14c8STreehugger Robot #if SANITIZER_LINUX && defined(__mips64)
44*7c3d14c8STreehugger Robot
45*7c3d14c8STreehugger Robot // Everything is above 0x00e000000000.
46*7c3d14c8STreehugger Robot const MappingDesc kMemoryLayout[] = {
47*7c3d14c8STreehugger Robot {0x000000000000ULL, 0x00a000000000ULL, MappingDesc::INVALID, "invalid"},
48*7c3d14c8STreehugger Robot {0x00a000000000ULL, 0x00c000000000ULL, MappingDesc::SHADOW, "shadow"},
49*7c3d14c8STreehugger Robot {0x00c000000000ULL, 0x00e000000000ULL, MappingDesc::ORIGIN, "origin"},
50*7c3d14c8STreehugger Robot {0x00e000000000ULL, 0x010000000000ULL, MappingDesc::APP, "app"}};
51*7c3d14c8STreehugger Robot
52*7c3d14c8STreehugger Robot #define MEM_TO_SHADOW(mem) (((uptr)(mem)) & ~0x4000000000ULL)
53*7c3d14c8STreehugger Robot #define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x002000000000)
54*7c3d14c8STreehugger Robot
55*7c3d14c8STreehugger Robot #elif SANITIZER_LINUX && defined(__aarch64__)
56*7c3d14c8STreehugger Robot
57*7c3d14c8STreehugger Robot // The mapping describes both 39-bits and 42-bits. AArch64 maps:
58*7c3d14c8STreehugger Robot // - 0x00000000000-0x00010000000: 39/42-bits program own segments
59*7c3d14c8STreehugger Robot // - 0x05500000000-0x05600000000: 39-bits PIE program segments
60*7c3d14c8STreehugger Robot // - 0x07f80000000-0x07fffffffff: 39-bits libraries segments
61*7c3d14c8STreehugger Robot // - 0x2aa00000000-0x2ab00000000: 42-bits PIE program segments
62*7c3d14c8STreehugger Robot // - 0x3ff00000000-0x3ffffffffff: 42-bits libraries segments
63*7c3d14c8STreehugger Robot // It is fragmented in multiples segments to increase the memory available
64*7c3d14c8STreehugger Robot // on 42-bits (12.21% of total VMA available for 42-bits and 13.28 for
65*7c3d14c8STreehugger Robot // 39 bits).
66*7c3d14c8STreehugger Robot const MappingDesc kMemoryLayout[] = {
67*7c3d14c8STreehugger Robot {0x00000000000ULL, 0x01000000000ULL, MappingDesc::INVALID, "invalid"},
68*7c3d14c8STreehugger Robot {0x01000000000ULL, 0x02000000000ULL, MappingDesc::SHADOW, "shadow-2"},
69*7c3d14c8STreehugger Robot {0x02000000000ULL, 0x03000000000ULL, MappingDesc::ORIGIN, "origin-2"},
70*7c3d14c8STreehugger Robot {0x03000000000ULL, 0x04000000000ULL, MappingDesc::SHADOW, "shadow-1"},
71*7c3d14c8STreehugger Robot {0x04000000000ULL, 0x05000000000ULL, MappingDesc::ORIGIN, "origin-1"},
72*7c3d14c8STreehugger Robot {0x05000000000ULL, 0x06000000000ULL, MappingDesc::APP, "app-1"},
73*7c3d14c8STreehugger Robot {0x06000000000ULL, 0x07000000000ULL, MappingDesc::INVALID, "invalid"},
74*7c3d14c8STreehugger Robot {0x07000000000ULL, 0x08000000000ULL, MappingDesc::APP, "app-2"},
75*7c3d14c8STreehugger Robot {0x08000000000ULL, 0x09000000000ULL, MappingDesc::INVALID, "invalid"},
76*7c3d14c8STreehugger Robot // The mappings below are used only for 42-bits VMA.
77*7c3d14c8STreehugger Robot {0x09000000000ULL, 0x0A000000000ULL, MappingDesc::SHADOW, "shadow-3"},
78*7c3d14c8STreehugger Robot {0x0A000000000ULL, 0x0B000000000ULL, MappingDesc::ORIGIN, "origin-3"},
79*7c3d14c8STreehugger Robot {0x0B000000000ULL, 0x0F000000000ULL, MappingDesc::INVALID, "invalid"},
80*7c3d14c8STreehugger Robot {0x0F000000000ULL, 0x10000000000ULL, MappingDesc::APP, "app-3"},
81*7c3d14c8STreehugger Robot {0x10000000000ULL, 0x11000000000ULL, MappingDesc::INVALID, "invalid"},
82*7c3d14c8STreehugger Robot {0x11000000000ULL, 0x12000000000ULL, MappingDesc::APP, "app-4"},
83*7c3d14c8STreehugger Robot {0x12000000000ULL, 0x17000000000ULL, MappingDesc::INVALID, "invalid"},
84*7c3d14c8STreehugger Robot {0x17000000000ULL, 0x18000000000ULL, MappingDesc::SHADOW, "shadow-4"},
85*7c3d14c8STreehugger Robot {0x18000000000ULL, 0x19000000000ULL, MappingDesc::ORIGIN, "origin-4"},
86*7c3d14c8STreehugger Robot {0x19000000000ULL, 0x20000000000ULL, MappingDesc::INVALID, "invalid"},
87*7c3d14c8STreehugger Robot {0x20000000000ULL, 0x21000000000ULL, MappingDesc::APP, "app-5"},
88*7c3d14c8STreehugger Robot {0x21000000000ULL, 0x26000000000ULL, MappingDesc::INVALID, "invalid"},
89*7c3d14c8STreehugger Robot {0x26000000000ULL, 0x27000000000ULL, MappingDesc::SHADOW, "shadow-5"},
90*7c3d14c8STreehugger Robot {0x27000000000ULL, 0x28000000000ULL, MappingDesc::ORIGIN, "origin-5"},
91*7c3d14c8STreehugger Robot {0x28000000000ULL, 0x29000000000ULL, MappingDesc::SHADOW, "shadow-7"},
92*7c3d14c8STreehugger Robot {0x29000000000ULL, 0x2A000000000ULL, MappingDesc::ORIGIN, "origin-7"},
93*7c3d14c8STreehugger Robot {0x2A000000000ULL, 0x2B000000000ULL, MappingDesc::APP, "app-6"},
94*7c3d14c8STreehugger Robot {0x2B000000000ULL, 0x2C000000000ULL, MappingDesc::INVALID, "invalid"},
95*7c3d14c8STreehugger Robot {0x2C000000000ULL, 0x2D000000000ULL, MappingDesc::SHADOW, "shadow-6"},
96*7c3d14c8STreehugger Robot {0x2D000000000ULL, 0x2E000000000ULL, MappingDesc::ORIGIN, "origin-6"},
97*7c3d14c8STreehugger Robot {0x2E000000000ULL, 0x2F000000000ULL, MappingDesc::APP, "app-7"},
98*7c3d14c8STreehugger Robot {0x2F000000000ULL, 0x39000000000ULL, MappingDesc::INVALID, "invalid"},
99*7c3d14c8STreehugger Robot {0x39000000000ULL, 0x3A000000000ULL, MappingDesc::SHADOW, "shadow-9"},
100*7c3d14c8STreehugger Robot {0x3A000000000ULL, 0x3B000000000ULL, MappingDesc::ORIGIN, "origin-9"},
101*7c3d14c8STreehugger Robot {0x3B000000000ULL, 0x3C000000000ULL, MappingDesc::APP, "app-8"},
102*7c3d14c8STreehugger Robot {0x3C000000000ULL, 0x3D000000000ULL, MappingDesc::INVALID, "invalid"},
103*7c3d14c8STreehugger Robot {0x3D000000000ULL, 0x3E000000000ULL, MappingDesc::SHADOW, "shadow-8"},
104*7c3d14c8STreehugger Robot {0x3E000000000ULL, 0x3F000000000ULL, MappingDesc::ORIGIN, "origin-8"},
105*7c3d14c8STreehugger Robot {0x3F000000000ULL, 0x40000000000ULL, MappingDesc::APP, "app-9"},
106*7c3d14c8STreehugger Robot };
107*7c3d14c8STreehugger Robot # define MEM_TO_SHADOW(mem) ((uptr)mem ^ 0x6000000000ULL)
108*7c3d14c8STreehugger Robot # define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x1000000000ULL)
109*7c3d14c8STreehugger Robot
110*7c3d14c8STreehugger Robot #elif SANITIZER_LINUX && SANITIZER_PPC64
111*7c3d14c8STreehugger Robot
112*7c3d14c8STreehugger Robot const MappingDesc kMemoryLayout[] = {
113*7c3d14c8STreehugger Robot {0x000000000000ULL, 0x000100000000ULL, MappingDesc::APP, "low memory"},
114*7c3d14c8STreehugger Robot {0x000100000000ULL, 0x080000000000ULL, MappingDesc::INVALID, "invalid"},
115*7c3d14c8STreehugger Robot {0x080000000000ULL, 0x180100000000ULL, MappingDesc::SHADOW, "shadow"},
116*7c3d14c8STreehugger Robot {0x180100000000ULL, 0x1C0000000000ULL, MappingDesc::INVALID, "invalid"},
117*7c3d14c8STreehugger Robot {0x1C0000000000ULL, 0x2C0100000000ULL, MappingDesc::ORIGIN, "origin"},
118*7c3d14c8STreehugger Robot {0x2C0100000000ULL, 0x300000000000ULL, MappingDesc::INVALID, "invalid"},
119*7c3d14c8STreehugger Robot {0x300000000000ULL, 0x400000000000ULL, MappingDesc::APP, "high memory"}};
120*7c3d14c8STreehugger Robot
121*7c3d14c8STreehugger Robot // Maps low and high app ranges to contiguous space with zero base:
122*7c3d14c8STreehugger Robot // Low: 0000 0000 0000 - 0000 ffff ffff -> 1000 0000 0000 - 1000 ffff ffff
123*7c3d14c8STreehugger Robot // High: 3000 0000 0000 - 3fff ffff ffff -> 0000 0000 0000 - 0fff ffff ffff
124*7c3d14c8STreehugger Robot #define LINEARIZE_MEM(mem) \
125*7c3d14c8STreehugger Robot (((uptr)(mem) & ~0x200000000000ULL) ^ 0x100000000000ULL)
126*7c3d14c8STreehugger Robot #define MEM_TO_SHADOW(mem) (LINEARIZE_MEM((mem)) + 0x080000000000ULL)
127*7c3d14c8STreehugger Robot #define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x140000000000ULL)
128*7c3d14c8STreehugger Robot
129*7c3d14c8STreehugger Robot #elif SANITIZER_FREEBSD && SANITIZER_WORDSIZE == 64
130*7c3d14c8STreehugger Robot
131*7c3d14c8STreehugger Robot // Low memory: main binary, MAP_32BIT mappings and modules
132*7c3d14c8STreehugger Robot // High memory: heap, modules and main thread stack
133*7c3d14c8STreehugger Robot const MappingDesc kMemoryLayout[] = {
134*7c3d14c8STreehugger Robot {0x000000000000ULL, 0x010000000000ULL, MappingDesc::APP, "low memory"},
135*7c3d14c8STreehugger Robot {0x010000000000ULL, 0x100000000000ULL, MappingDesc::INVALID, "invalid"},
136*7c3d14c8STreehugger Robot {0x100000000000ULL, 0x310000000000ULL, MappingDesc::SHADOW, "shadow"},
137*7c3d14c8STreehugger Robot {0x310000000000ULL, 0x380000000000ULL, MappingDesc::INVALID, "invalid"},
138*7c3d14c8STreehugger Robot {0x380000000000ULL, 0x590000000000ULL, MappingDesc::ORIGIN, "origin"},
139*7c3d14c8STreehugger Robot {0x590000000000ULL, 0x600000000000ULL, MappingDesc::INVALID, "invalid"},
140*7c3d14c8STreehugger Robot {0x600000000000ULL, 0x800000000000ULL, MappingDesc::APP, "high memory"}};
141*7c3d14c8STreehugger Robot
142*7c3d14c8STreehugger Robot // Maps low and high app ranges to contiguous space with zero base:
143*7c3d14c8STreehugger Robot // Low: 0000 0000 0000 - 00ff ffff ffff -> 2000 0000 0000 - 20ff ffff ffff
144*7c3d14c8STreehugger Robot // High: 6000 0000 0000 - 7fff ffff ffff -> 0000 0000 0000 - 1fff ffff ffff
145*7c3d14c8STreehugger Robot #define LINEARIZE_MEM(mem) \
146*7c3d14c8STreehugger Robot (((uptr)(mem) & ~0xc00000000000ULL) ^ 0x200000000000ULL)
147*7c3d14c8STreehugger Robot #define MEM_TO_SHADOW(mem) (LINEARIZE_MEM((mem)) + 0x100000000000ULL)
148*7c3d14c8STreehugger Robot #define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x280000000000)
149*7c3d14c8STreehugger Robot
150*7c3d14c8STreehugger Robot #elif SANITIZER_LINUX && SANITIZER_WORDSIZE == 64
151*7c3d14c8STreehugger Robot
152*7c3d14c8STreehugger Robot #ifdef MSAN_LINUX_X86_64_OLD_MAPPING
153*7c3d14c8STreehugger Robot // Requries PIE binary and ASLR enabled.
154*7c3d14c8STreehugger Robot // Main thread stack and DSOs at 0x7f0000000000 (sometimes 0x7e0000000000).
155*7c3d14c8STreehugger Robot // Heap at 0x600000000000.
156*7c3d14c8STreehugger Robot const MappingDesc kMemoryLayout[] = {
157*7c3d14c8STreehugger Robot {0x000000000000ULL, 0x200000000000ULL, MappingDesc::INVALID, "invalid"},
158*7c3d14c8STreehugger Robot {0x200000000000ULL, 0x400000000000ULL, MappingDesc::SHADOW, "shadow"},
159*7c3d14c8STreehugger Robot {0x400000000000ULL, 0x600000000000ULL, MappingDesc::ORIGIN, "origin"},
160*7c3d14c8STreehugger Robot {0x600000000000ULL, 0x800000000000ULL, MappingDesc::APP, "app"}};
161*7c3d14c8STreehugger Robot
162*7c3d14c8STreehugger Robot #define MEM_TO_SHADOW(mem) (((uptr)(mem)) & ~0x400000000000ULL)
163*7c3d14c8STreehugger Robot #define SHADOW_TO_ORIGIN(mem) (((uptr)(mem)) + 0x200000000000ULL)
164*7c3d14c8STreehugger Robot #else // MSAN_LINUX_X86_64_OLD_MAPPING
165*7c3d14c8STreehugger Robot // All of the following configurations are supported.
166*7c3d14c8STreehugger Robot // ASLR disabled: main executable and DSOs at 0x555550000000
167*7c3d14c8STreehugger Robot // PIE and ASLR: main executable and DSOs at 0x7f0000000000
168*7c3d14c8STreehugger Robot // non-PIE: main executable below 0x100000000, DSOs at 0x7f0000000000
169*7c3d14c8STreehugger Robot // Heap at 0x700000000000.
170*7c3d14c8STreehugger Robot const MappingDesc kMemoryLayout[] = {
171*7c3d14c8STreehugger Robot {0x000000000000ULL, 0x010000000000ULL, MappingDesc::APP, "app-1"},
172*7c3d14c8STreehugger Robot {0x010000000000ULL, 0x100000000000ULL, MappingDesc::SHADOW, "shadow-2"},
173*7c3d14c8STreehugger Robot {0x100000000000ULL, 0x110000000000ULL, MappingDesc::INVALID, "invalid"},
174*7c3d14c8STreehugger Robot {0x110000000000ULL, 0x200000000000ULL, MappingDesc::ORIGIN, "origin-2"},
175*7c3d14c8STreehugger Robot {0x200000000000ULL, 0x300000000000ULL, MappingDesc::SHADOW, "shadow-3"},
176*7c3d14c8STreehugger Robot {0x300000000000ULL, 0x400000000000ULL, MappingDesc::ORIGIN, "origin-3"},
177*7c3d14c8STreehugger Robot {0x400000000000ULL, 0x500000000000ULL, MappingDesc::INVALID, "invalid"},
178*7c3d14c8STreehugger Robot {0x500000000000ULL, 0x510000000000ULL, MappingDesc::SHADOW, "shadow-1"},
179*7c3d14c8STreehugger Robot {0x510000000000ULL, 0x600000000000ULL, MappingDesc::APP, "app-2"},
180*7c3d14c8STreehugger Robot {0x600000000000ULL, 0x610000000000ULL, MappingDesc::ORIGIN, "origin-1"},
181*7c3d14c8STreehugger Robot {0x610000000000ULL, 0x700000000000ULL, MappingDesc::INVALID, "invalid"},
182*7c3d14c8STreehugger Robot {0x700000000000ULL, 0x800000000000ULL, MappingDesc::APP, "app-3"}};
183*7c3d14c8STreehugger Robot #define MEM_TO_SHADOW(mem) (((uptr)(mem)) ^ 0x500000000000ULL)
184*7c3d14c8STreehugger Robot #define SHADOW_TO_ORIGIN(mem) (((uptr)(mem)) + 0x100000000000ULL)
185*7c3d14c8STreehugger Robot #endif // MSAN_LINUX_X86_64_OLD_MAPPING
186*7c3d14c8STreehugger Robot
187*7c3d14c8STreehugger Robot #else
188*7c3d14c8STreehugger Robot #error "Unsupported platform"
189*7c3d14c8STreehugger Robot #endif
190*7c3d14c8STreehugger Robot
191*7c3d14c8STreehugger Robot const uptr kMemoryLayoutSize = sizeof(kMemoryLayout) / sizeof(kMemoryLayout[0]);
192*7c3d14c8STreehugger Robot
193*7c3d14c8STreehugger Robot #define MEM_TO_ORIGIN(mem) (SHADOW_TO_ORIGIN(MEM_TO_SHADOW((mem))))
194*7c3d14c8STreehugger Robot
195*7c3d14c8STreehugger Robot #ifndef __clang__
196*7c3d14c8STreehugger Robot __attribute__((optimize("unroll-loops")))
197*7c3d14c8STreehugger Robot #endif
addr_is_type(uptr addr,MappingDesc::Type mapping_type)198*7c3d14c8STreehugger Robot inline bool addr_is_type(uptr addr, MappingDesc::Type mapping_type) {
199*7c3d14c8STreehugger Robot // It is critical for performance that this loop is unrolled (because then it is
200*7c3d14c8STreehugger Robot // simplified into just a few constant comparisons).
201*7c3d14c8STreehugger Robot #ifdef __clang__
202*7c3d14c8STreehugger Robot #pragma unroll
203*7c3d14c8STreehugger Robot #endif
204*7c3d14c8STreehugger Robot for (unsigned i = 0; i < kMemoryLayoutSize; ++i)
205*7c3d14c8STreehugger Robot if (kMemoryLayout[i].type == mapping_type &&
206*7c3d14c8STreehugger Robot addr >= kMemoryLayout[i].start && addr < kMemoryLayout[i].end)
207*7c3d14c8STreehugger Robot return true;
208*7c3d14c8STreehugger Robot return false;
209*7c3d14c8STreehugger Robot }
210*7c3d14c8STreehugger Robot
211*7c3d14c8STreehugger Robot #define MEM_IS_APP(mem) addr_is_type((uptr)(mem), MappingDesc::APP)
212*7c3d14c8STreehugger Robot #define MEM_IS_SHADOW(mem) addr_is_type((uptr)(mem), MappingDesc::SHADOW)
213*7c3d14c8STreehugger Robot #define MEM_IS_ORIGIN(mem) addr_is_type((uptr)(mem), MappingDesc::ORIGIN)
214*7c3d14c8STreehugger Robot
215*7c3d14c8STreehugger Robot // These constants must be kept in sync with the ones in MemorySanitizer.cc.
216*7c3d14c8STreehugger Robot const int kMsanParamTlsSize = 800;
217*7c3d14c8STreehugger Robot const int kMsanRetvalTlsSize = 800;
218*7c3d14c8STreehugger Robot
219*7c3d14c8STreehugger Robot namespace __msan {
220*7c3d14c8STreehugger Robot extern int msan_inited;
221*7c3d14c8STreehugger Robot extern bool msan_init_is_running;
222*7c3d14c8STreehugger Robot extern int msan_report_count;
223*7c3d14c8STreehugger Robot
224*7c3d14c8STreehugger Robot bool ProtectRange(uptr beg, uptr end);
225*7c3d14c8STreehugger Robot bool InitShadow(bool init_origins);
226*7c3d14c8STreehugger Robot char *GetProcSelfMaps();
227*7c3d14c8STreehugger Robot void InitializeInterceptors();
228*7c3d14c8STreehugger Robot
229*7c3d14c8STreehugger Robot void MsanAllocatorInit();
230*7c3d14c8STreehugger Robot void MsanAllocatorThreadFinish();
231*7c3d14c8STreehugger Robot void *MsanCalloc(StackTrace *stack, uptr nmemb, uptr size);
232*7c3d14c8STreehugger Robot void *MsanReallocate(StackTrace *stack, void *oldp, uptr size,
233*7c3d14c8STreehugger Robot uptr alignment, bool zeroise);
234*7c3d14c8STreehugger Robot void MsanDeallocate(StackTrace *stack, void *ptr);
235*7c3d14c8STreehugger Robot void InstallTrapHandler();
236*7c3d14c8STreehugger Robot void InstallAtExitHandler();
237*7c3d14c8STreehugger Robot
238*7c3d14c8STreehugger Robot const char *GetStackOriginDescr(u32 id, uptr *pc);
239*7c3d14c8STreehugger Robot
240*7c3d14c8STreehugger Robot void EnterSymbolizer();
241*7c3d14c8STreehugger Robot void ExitSymbolizer();
242*7c3d14c8STreehugger Robot bool IsInSymbolizer();
243*7c3d14c8STreehugger Robot
244*7c3d14c8STreehugger Robot struct SymbolizerScope {
SymbolizerScopeSymbolizerScope245*7c3d14c8STreehugger Robot SymbolizerScope() { EnterSymbolizer(); }
~SymbolizerScopeSymbolizerScope246*7c3d14c8STreehugger Robot ~SymbolizerScope() { ExitSymbolizer(); }
247*7c3d14c8STreehugger Robot };
248*7c3d14c8STreehugger Robot
249*7c3d14c8STreehugger Robot void PrintWarning(uptr pc, uptr bp);
250*7c3d14c8STreehugger Robot void PrintWarningWithOrigin(uptr pc, uptr bp, u32 origin);
251*7c3d14c8STreehugger Robot
252*7c3d14c8STreehugger Robot void GetStackTrace(BufferedStackTrace *stack, uptr max_s, uptr pc, uptr bp,
253*7c3d14c8STreehugger Robot bool request_fast_unwind);
254*7c3d14c8STreehugger Robot
255*7c3d14c8STreehugger Robot void ReportUMR(StackTrace *stack, u32 origin);
256*7c3d14c8STreehugger Robot void ReportExpectedUMRNotFound(StackTrace *stack);
257*7c3d14c8STreehugger Robot void ReportStats();
258*7c3d14c8STreehugger Robot void ReportAtExitStatistics();
259*7c3d14c8STreehugger Robot void DescribeMemoryRange(const void *x, uptr size);
260*7c3d14c8STreehugger Robot void ReportUMRInsideAddressRange(const char *what, const void *start, uptr size,
261*7c3d14c8STreehugger Robot uptr offset);
262*7c3d14c8STreehugger Robot
263*7c3d14c8STreehugger Robot // Unpoison first n function arguments.
264*7c3d14c8STreehugger Robot void UnpoisonParam(uptr n);
265*7c3d14c8STreehugger Robot void UnpoisonThreadLocalState();
266*7c3d14c8STreehugger Robot
267*7c3d14c8STreehugger Robot // Returns a "chained" origin id, pointing to the given stack trace followed by
268*7c3d14c8STreehugger Robot // the previous origin id.
269*7c3d14c8STreehugger Robot u32 ChainOrigin(u32 id, StackTrace *stack);
270*7c3d14c8STreehugger Robot
271*7c3d14c8STreehugger Robot const int STACK_TRACE_TAG_POISON = StackTrace::TAG_CUSTOM + 1;
272*7c3d14c8STreehugger Robot
273*7c3d14c8STreehugger Robot #define GET_MALLOC_STACK_TRACE \
274*7c3d14c8STreehugger Robot BufferedStackTrace stack; \
275*7c3d14c8STreehugger Robot if (__msan_get_track_origins() && msan_inited) \
276*7c3d14c8STreehugger Robot GetStackTrace(&stack, common_flags()->malloc_context_size, \
277*7c3d14c8STreehugger Robot StackTrace::GetCurrentPc(), GET_CURRENT_FRAME(), \
278*7c3d14c8STreehugger Robot common_flags()->fast_unwind_on_malloc)
279*7c3d14c8STreehugger Robot
280*7c3d14c8STreehugger Robot #define GET_STORE_STACK_TRACE_PC_BP(pc, bp) \
281*7c3d14c8STreehugger Robot BufferedStackTrace stack; \
282*7c3d14c8STreehugger Robot if (__msan_get_track_origins() > 1 && msan_inited) \
283*7c3d14c8STreehugger Robot GetStackTrace(&stack, flags()->store_context_size, pc, bp, \
284*7c3d14c8STreehugger Robot common_flags()->fast_unwind_on_malloc)
285*7c3d14c8STreehugger Robot
286*7c3d14c8STreehugger Robot #define GET_FATAL_STACK_TRACE_PC_BP(pc, bp) \
287*7c3d14c8STreehugger Robot BufferedStackTrace stack; \
288*7c3d14c8STreehugger Robot if (msan_inited) \
289*7c3d14c8STreehugger Robot GetStackTrace(&stack, kStackTraceMax, pc, bp, \
290*7c3d14c8STreehugger Robot common_flags()->fast_unwind_on_fatal)
291*7c3d14c8STreehugger Robot
292*7c3d14c8STreehugger Robot #define GET_STORE_STACK_TRACE \
293*7c3d14c8STreehugger Robot GET_STORE_STACK_TRACE_PC_BP(StackTrace::GetCurrentPc(), GET_CURRENT_FRAME())
294*7c3d14c8STreehugger Robot
295*7c3d14c8STreehugger Robot class ScopedThreadLocalStateBackup {
296*7c3d14c8STreehugger Robot public:
ScopedThreadLocalStateBackup()297*7c3d14c8STreehugger Robot ScopedThreadLocalStateBackup() { Backup(); }
~ScopedThreadLocalStateBackup()298*7c3d14c8STreehugger Robot ~ScopedThreadLocalStateBackup() { Restore(); }
299*7c3d14c8STreehugger Robot void Backup();
300*7c3d14c8STreehugger Robot void Restore();
301*7c3d14c8STreehugger Robot private:
302*7c3d14c8STreehugger Robot u64 va_arg_overflow_size_tls;
303*7c3d14c8STreehugger Robot };
304*7c3d14c8STreehugger Robot
305*7c3d14c8STreehugger Robot void MsanTSDInit(void (*destructor)(void *tsd));
306*7c3d14c8STreehugger Robot void *MsanTSDGet();
307*7c3d14c8STreehugger Robot void MsanTSDSet(void *tsd);
308*7c3d14c8STreehugger Robot void MsanTSDDtor(void *tsd);
309*7c3d14c8STreehugger Robot
310*7c3d14c8STreehugger Robot } // namespace __msan
311*7c3d14c8STreehugger Robot
312*7c3d14c8STreehugger Robot #define MSAN_MALLOC_HOOK(ptr, size) \
313*7c3d14c8STreehugger Robot do { \
314*7c3d14c8STreehugger Robot if (&__sanitizer_malloc_hook) { \
315*7c3d14c8STreehugger Robot UnpoisonParam(2); \
316*7c3d14c8STreehugger Robot __sanitizer_malloc_hook(ptr, size); \
317*7c3d14c8STreehugger Robot } \
318*7c3d14c8STreehugger Robot RunMallocHooks(ptr, size); \
319*7c3d14c8STreehugger Robot } while (false)
320*7c3d14c8STreehugger Robot #define MSAN_FREE_HOOK(ptr) \
321*7c3d14c8STreehugger Robot do { \
322*7c3d14c8STreehugger Robot if (&__sanitizer_free_hook) { \
323*7c3d14c8STreehugger Robot UnpoisonParam(1); \
324*7c3d14c8STreehugger Robot __sanitizer_free_hook(ptr); \
325*7c3d14c8STreehugger Robot } \
326*7c3d14c8STreehugger Robot RunFreeHooks(ptr); \
327*7c3d14c8STreehugger Robot } while (false)
328*7c3d14c8STreehugger Robot
329*7c3d14c8STreehugger Robot #endif // MSAN_H
330