blob: 2079a592b7b9d4910871e9b4c7ccef5e2858f49d [file] [log] [blame]
Evgeniy Stepanov97edeb32012-12-25 11:53:51 +00001//===-- msan.h --------------------------------------------------*- C++ -*-===//
Evgeniy Stepanov78c56c32012-12-11 12:27:27 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file is a part of MemorySanitizer.
11//
12// Private MSan header.
13//===----------------------------------------------------------------------===//
14
15#ifndef MSAN_H
16#define MSAN_H
17
Sergey Matveev0b4bf4d2013-05-06 13:15:14 +000018#include "sanitizer_common/sanitizer_flags.h"
Evgeniy Stepanov78c56c32012-12-11 12:27:27 +000019#include "sanitizer_common/sanitizer_internal_defs.h"
20#include "sanitizer_common/sanitizer_stacktrace.h"
Evgeniy Stepanov12c46932013-01-29 14:33:29 +000021#include "msan_interface_internal.h"
Evgeniy Stepanov78c56c32012-12-11 12:27:27 +000022#include "msan_flags.h"
Pirama Arumuga Nainarcdce50b2015-07-01 12:26:56 -070023#include "ubsan/ubsan_platform.h"
Evgeniy Stepanov78c56c32012-12-11 12:27:27 +000024
Evgeniy Stepanova8974002013-04-05 12:03:47 +000025#ifndef MSAN_REPLACE_OPERATORS_NEW_AND_DELETE
26# define MSAN_REPLACE_OPERATORS_NEW_AND_DELETE 1
27#endif
28
Pirama Arumuga Nainarcdce50b2015-07-01 12:26:56 -070029#ifndef MSAN_CONTAINS_UBSAN
30# define MSAN_CONTAINS_UBSAN CAN_SANITIZE_UB
31#endif
32
Stephen Hines86277eb2015-03-23 12:06:32 -070033struct MappingDesc {
34 uptr start;
35 uptr end;
36 enum Type {
37 INVALID, APP, SHADOW, ORIGIN
38 } type;
39 const char *name;
40};
41
42
43#if SANITIZER_LINUX && defined(__mips64)
44
45// Everything is above 0x00e000000000.
46const MappingDesc kMemoryLayout[] = {
47 {0x000000000000ULL, 0x00a000000000ULL, MappingDesc::INVALID, "invalid"},
48 {0x00a000000000ULL, 0x00c000000000ULL, MappingDesc::SHADOW, "shadow"},
49 {0x00c000000000ULL, 0x00e000000000ULL, MappingDesc::ORIGIN, "origin"},
50 {0x00e000000000ULL, 0x010000000000ULL, MappingDesc::APP, "app"}};
51
52#define MEM_TO_SHADOW(mem) (((uptr)(mem)) & ~0x4000000000ULL)
53#define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x002000000000)
54
Pirama Arumuga Nainar799172d2016-03-03 15:50:30 -080055#elif SANITIZER_LINUX && defined(__aarch64__)
56
57// The mapping describes both 39-bits and 42-bits. AArch64 maps:
58// - 0x00000000000-0x00010000000: 39/42-bits program own segments
59// - 0x05500000000-0x05600000000: 39-bits PIE program segments
60// - 0x07f80000000-0x07fffffffff: 39-bits libraries segments
61// - 0x2aa00000000-0x2ab00000000: 42-bits PIE program segments
62// - 0x3ff00000000-0x3ffffffffff: 42-bits libraries segments
63// It is fragmented in multiples segments to increase the memory available
64// on 42-bits (12.21% of total VMA available for 42-bits and 13.28 for
65// 39 bits).
66const MappingDesc kMemoryLayout[] = {
67 {0x00000000000ULL, 0x01000000000ULL, MappingDesc::INVALID, "invalid"},
68 {0x01000000000ULL, 0x02000000000ULL, MappingDesc::SHADOW, "shadow-2"},
69 {0x02000000000ULL, 0x03000000000ULL, MappingDesc::ORIGIN, "origin-2"},
70 {0x03000000000ULL, 0x04000000000ULL, MappingDesc::SHADOW, "shadow-1"},
71 {0x04000000000ULL, 0x05000000000ULL, MappingDesc::ORIGIN, "origin-1"},
72 {0x05000000000ULL, 0x06000000000ULL, MappingDesc::APP, "app-1"},
73 {0x06000000000ULL, 0x07000000000ULL, MappingDesc::INVALID, "invalid"},
74 {0x07000000000ULL, 0x08000000000ULL, MappingDesc::APP, "app-2"},
75 {0x08000000000ULL, 0x09000000000ULL, MappingDesc::INVALID, "invalid"},
76 // The mappings below are used only for 42-bits VMA.
77 {0x09000000000ULL, 0x0A000000000ULL, MappingDesc::SHADOW, "shadow-3"},
78 {0x0A000000000ULL, 0x0B000000000ULL, MappingDesc::ORIGIN, "origin-3"},
79 {0x0B000000000ULL, 0x0F000000000ULL, MappingDesc::INVALID, "invalid"},
80 {0x0F000000000ULL, 0x10000000000ULL, MappingDesc::APP, "app-3"},
81 {0x10000000000ULL, 0x11000000000ULL, MappingDesc::INVALID, "invalid"},
82 {0x11000000000ULL, 0x12000000000ULL, MappingDesc::APP, "app-4"},
83 {0x12000000000ULL, 0x17000000000ULL, MappingDesc::INVALID, "invalid"},
84 {0x17000000000ULL, 0x18000000000ULL, MappingDesc::SHADOW, "shadow-4"},
85 {0x18000000000ULL, 0x19000000000ULL, MappingDesc::ORIGIN, "origin-4"},
86 {0x19000000000ULL, 0x20000000000ULL, MappingDesc::INVALID, "invalid"},
87 {0x20000000000ULL, 0x21000000000ULL, MappingDesc::APP, "app-5"},
88 {0x21000000000ULL, 0x26000000000ULL, MappingDesc::INVALID, "invalid"},
89 {0x26000000000ULL, 0x27000000000ULL, MappingDesc::SHADOW, "shadow-5"},
90 {0x27000000000ULL, 0x28000000000ULL, MappingDesc::ORIGIN, "origin-5"},
91 {0x28000000000ULL, 0x29000000000ULL, MappingDesc::SHADOW, "shadow-7"},
92 {0x29000000000ULL, 0x2A000000000ULL, MappingDesc::ORIGIN, "origin-7"},
93 {0x2A000000000ULL, 0x2B000000000ULL, MappingDesc::APP, "app-6"},
94 {0x2B000000000ULL, 0x2C000000000ULL, MappingDesc::INVALID, "invalid"},
95 {0x2C000000000ULL, 0x2D000000000ULL, MappingDesc::SHADOW, "shadow-6"},
96 {0x2D000000000ULL, 0x2E000000000ULL, MappingDesc::ORIGIN, "origin-6"},
97 {0x2E000000000ULL, 0x2F000000000ULL, MappingDesc::APP, "app-7"},
98 {0x2F000000000ULL, 0x39000000000ULL, MappingDesc::INVALID, "invalid"},
99 {0x39000000000ULL, 0x3A000000000ULL, MappingDesc::SHADOW, "shadow-9"},
100 {0x3A000000000ULL, 0x3B000000000ULL, MappingDesc::ORIGIN, "origin-9"},
101 {0x3B000000000ULL, 0x3C000000000ULL, MappingDesc::APP, "app-8"},
102 {0x3C000000000ULL, 0x3D000000000ULL, MappingDesc::INVALID, "invalid"},
103 {0x3D000000000ULL, 0x3E000000000ULL, MappingDesc::SHADOW, "shadow-8"},
104 {0x3E000000000ULL, 0x3F000000000ULL, MappingDesc::ORIGIN, "origin-8"},
105 {0x3F000000000ULL, 0x40000000000ULL, MappingDesc::APP, "app-9"},
106};
107# define MEM_TO_SHADOW(mem) ((uptr)mem ^ 0x6000000000ULL)
108# define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x1000000000ULL)
109
110#elif SANITIZER_LINUX && defined(__powerpc64__)
111
112const MappingDesc kMemoryLayout[] = {
113 {0x000000000000ULL, 0x000100000000ULL, MappingDesc::APP, "low memory"},
114 {0x000100000000ULL, 0x080000000000ULL, MappingDesc::INVALID, "invalid"},
115 {0x080000000000ULL, 0x180100000000ULL, MappingDesc::SHADOW, "shadow"},
116 {0x180100000000ULL, 0x1C0000000000ULL, MappingDesc::INVALID, "invalid"},
117 {0x1C0000000000ULL, 0x2C0100000000ULL, MappingDesc::ORIGIN, "origin"},
118 {0x2C0100000000ULL, 0x300000000000ULL, MappingDesc::INVALID, "invalid"},
119 {0x300000000000ULL, 0x400000000000ULL, MappingDesc::APP, "high memory"}};
120
121// Maps low and high app ranges to contiguous space with zero base:
122// Low: 0000 0000 0000 - 0000 ffff ffff -> 1000 0000 0000 - 1000 ffff ffff
123// High: 3000 0000 0000 - 3fff ffff ffff -> 0000 0000 0000 - 0fff ffff ffff
124#define LINEARIZE_MEM(mem) \
125 (((uptr)(mem) & ~0x200000000000ULL) ^ 0x100000000000ULL)
126#define MEM_TO_SHADOW(mem) (LINEARIZE_MEM((mem)) + 0x080000000000ULL)
127#define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x140000000000ULL)
128
Stephen Hines86277eb2015-03-23 12:06:32 -0700129#elif SANITIZER_FREEBSD && SANITIZER_WORDSIZE == 64
130
131// Low memory: main binary, MAP_32BIT mappings and modules
132// High memory: heap, modules and main thread stack
133const MappingDesc kMemoryLayout[] = {
134 {0x000000000000ULL, 0x010000000000ULL, MappingDesc::APP, "low memory"},
135 {0x010000000000ULL, 0x100000000000ULL, MappingDesc::INVALID, "invalid"},
136 {0x100000000000ULL, 0x310000000000ULL, MappingDesc::SHADOW, "shadow"},
137 {0x310000000000ULL, 0x380000000000ULL, MappingDesc::INVALID, "invalid"},
138 {0x380000000000ULL, 0x590000000000ULL, MappingDesc::ORIGIN, "origin"},
139 {0x590000000000ULL, 0x600000000000ULL, MappingDesc::INVALID, "invalid"},
140 {0x600000000000ULL, 0x800000000000ULL, MappingDesc::APP, "high memory"}};
141
142// Maps low and high app ranges to contiguous space with zero base:
143// Low: 0000 0000 0000 - 00ff ffff ffff -> 2000 0000 0000 - 20ff ffff ffff
144// High: 6000 0000 0000 - 7fff ffff ffff -> 0000 0000 0000 - 1fff ffff ffff
145#define LINEARIZE_MEM(mem) \
146 (((uptr)(mem) & ~0xc00000000000ULL) ^ 0x200000000000ULL)
147#define MEM_TO_SHADOW(mem) (LINEARIZE_MEM((mem)) + 0x100000000000ULL)
148#define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x280000000000)
149
150#elif SANITIZER_LINUX && SANITIZER_WORDSIZE == 64
151
Pirama Arumuga Nainar799172d2016-03-03 15:50:30 -0800152#ifdef MSAN_LINUX_X86_64_OLD_MAPPING
Stephen Hines86277eb2015-03-23 12:06:32 -0700153// Requries PIE binary and ASLR enabled.
154// Main thread stack and DSOs at 0x7f0000000000 (sometimes 0x7e0000000000).
155// Heap at 0x600000000000.
156const MappingDesc kMemoryLayout[] = {
157 {0x000000000000ULL, 0x200000000000ULL, MappingDesc::INVALID, "invalid"},
158 {0x200000000000ULL, 0x400000000000ULL, MappingDesc::SHADOW, "shadow"},
159 {0x400000000000ULL, 0x600000000000ULL, MappingDesc::ORIGIN, "origin"},
160 {0x600000000000ULL, 0x800000000000ULL, MappingDesc::APP, "app"}};
161
162#define MEM_TO_SHADOW(mem) (((uptr)(mem)) & ~0x400000000000ULL)
163#define SHADOW_TO_ORIGIN(mem) (((uptr)(mem)) + 0x200000000000ULL)
Pirama Arumuga Nainar799172d2016-03-03 15:50:30 -0800164#else // MSAN_LINUX_X86_64_OLD_MAPPING
165// All of the following configurations are supported.
166// ASLR disabled: main executable and DSOs at 0x555550000000
167// PIE and ASLR: main executable and DSOs at 0x7f0000000000
168// non-PIE: main executable below 0x100000000, DSOs at 0x7f0000000000
169// Heap at 0x700000000000.
170const MappingDesc kMemoryLayout[] = {
171 {0x000000000000ULL, 0x010000000000ULL, MappingDesc::APP, "app-1"},
172 {0x010000000000ULL, 0x100000000000ULL, MappingDesc::SHADOW, "shadow-2"},
173 {0x100000000000ULL, 0x110000000000ULL, MappingDesc::INVALID, "invalid"},
174 {0x110000000000ULL, 0x200000000000ULL, MappingDesc::ORIGIN, "origin-2"},
175 {0x200000000000ULL, 0x300000000000ULL, MappingDesc::SHADOW, "shadow-3"},
176 {0x300000000000ULL, 0x400000000000ULL, MappingDesc::ORIGIN, "origin-3"},
177 {0x400000000000ULL, 0x500000000000ULL, MappingDesc::INVALID, "invalid"},
178 {0x500000000000ULL, 0x510000000000ULL, MappingDesc::SHADOW, "shadow-1"},
179 {0x510000000000ULL, 0x600000000000ULL, MappingDesc::APP, "app-2"},
180 {0x600000000000ULL, 0x610000000000ULL, MappingDesc::ORIGIN, "origin-1"},
181 {0x610000000000ULL, 0x700000000000ULL, MappingDesc::INVALID, "invalid"},
182 {0x700000000000ULL, 0x800000000000ULL, MappingDesc::APP, "app-3"}};
183#define MEM_TO_SHADOW(mem) (((uptr)(mem)) ^ 0x500000000000ULL)
184#define SHADOW_TO_ORIGIN(mem) (((uptr)(mem)) + 0x100000000000ULL)
185#endif // MSAN_LINUX_X86_64_OLD_MAPPING
Stephen Hines86277eb2015-03-23 12:06:32 -0700186
187#else
188#error "Unsupported platform"
Stephen Hines6d186232014-11-26 17:56:19 -0800189#endif
Evgeniy Stepanov78c56c32012-12-11 12:27:27 +0000190
Stephen Hines86277eb2015-03-23 12:06:32 -0700191const uptr kMemoryLayoutSize = sizeof(kMemoryLayout) / sizeof(kMemoryLayout[0]);
192
193#define MEM_TO_ORIGIN(mem) (SHADOW_TO_ORIGIN(MEM_TO_SHADOW((mem))))
194
195#ifndef __clang__
196__attribute__((optimize("unroll-loops")))
197#endif
198inline bool addr_is_type(uptr addr, MappingDesc::Type mapping_type) {
199// It is critical for performance that this loop is unrolled (because then it is
200// simplified into just a few constant comparisons).
201#ifdef __clang__
202#pragma unroll
203#endif
204 for (unsigned i = 0; i < kMemoryLayoutSize; ++i)
205 if (kMemoryLayout[i].type == mapping_type &&
206 addr >= kMemoryLayout[i].start && addr < kMemoryLayout[i].end)
207 return true;
208 return false;
209}
210
211#define MEM_IS_APP(mem) addr_is_type((uptr)(mem), MappingDesc::APP)
212#define MEM_IS_SHADOW(mem) addr_is_type((uptr)(mem), MappingDesc::SHADOW)
213#define MEM_IS_ORIGIN(mem) addr_is_type((uptr)(mem), MappingDesc::ORIGIN)
214
Stephen Hines6d186232014-11-26 17:56:19 -0800215// These constants must be kept in sync with the ones in MemorySanitizer.cc.
216const int kMsanParamTlsSize = 800;
217const int kMsanRetvalTlsSize = 800;
Evgeniy Stepanov78c56c32012-12-11 12:27:27 +0000218
219namespace __msan {
220extern int msan_inited;
221extern bool msan_init_is_running;
Evgeniy Stepanov99bf1d72013-01-10 11:17:55 +0000222extern int msan_report_count;
Evgeniy Stepanov78c56c32012-12-11 12:27:27 +0000223
224bool ProtectRange(uptr beg, uptr end);
Pirama Arumuga Nainarcdce50b2015-07-01 12:26:56 -0700225bool InitShadow(bool init_origins);
Evgeniy Stepanov78c56c32012-12-11 12:27:27 +0000226char *GetProcSelfMaps();
227void InitializeInterceptors();
228
Pirama Arumuga Nainar799172d2016-03-03 15:50:30 -0800229void MsanAllocatorInit();
Evgeniy Stepanov7c6bd402013-10-22 14:31:30 +0000230void MsanAllocatorThreadFinish();
Stephen Hines86277eb2015-03-23 12:06:32 -0700231void *MsanCalloc(StackTrace *stack, uptr nmemb, uptr size);
Evgeniy Stepanov78c56c32012-12-11 12:27:27 +0000232void *MsanReallocate(StackTrace *stack, void *oldp, uptr size,
233 uptr alignment, bool zeroise);
Evgeniy Stepanoveffdc7e2013-09-16 11:03:31 +0000234void MsanDeallocate(StackTrace *stack, void *ptr);
Evgeniy Stepanov78c56c32012-12-11 12:27:27 +0000235void InstallTrapHandler();
Evgeniy Stepanov99bf1d72013-01-10 11:17:55 +0000236void InstallAtExitHandler();
Evgeniy Stepanov78c56c32012-12-11 12:27:27 +0000237
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700238const char *GetStackOriginDescr(u32 id, uptr *pc);
Evgeniy Stepanov6f346052013-09-13 12:49:13 +0000239
Kostya Serebryany70c6e3f2013-02-13 07:19:47 +0000240void EnterSymbolizer();
241void ExitSymbolizer();
242bool IsInSymbolizer();
243
Reid Kleckner93c26022013-03-06 16:11:58 +0000244struct SymbolizerScope {
245 SymbolizerScope() { EnterSymbolizer(); }
246 ~SymbolizerScope() { ExitSymbolizer(); }
247};
248
Evgeniy Stepanov78c56c32012-12-11 12:27:27 +0000249void PrintWarning(uptr pc, uptr bp);
250void PrintWarningWithOrigin(uptr pc, uptr bp, u32 origin);
251
Stephen Hines6d186232014-11-26 17:56:19 -0800252void GetStackTrace(BufferedStackTrace *stack, uptr max_s, uptr pc, uptr bp,
Alexey Samsonovf16dc422013-11-07 07:28:33 +0000253 bool request_fast_unwind);
Evgeniy Stepanov78c56c32012-12-11 12:27:27 +0000254
Evgeniy Stepanovdb010da2012-12-26 09:32:05 +0000255void ReportUMR(StackTrace *stack, u32 origin);
256void ReportExpectedUMRNotFound(StackTrace *stack);
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700257void ReportStats();
Evgeniy Stepanov99bf1d72013-01-10 11:17:55 +0000258void ReportAtExitStatistics();
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700259void DescribeMemoryRange(const void *x, uptr size);
260void ReportUMRInsideAddressRange(const char *what, const void *start, uptr size,
261 uptr offset);
Evgeniy Stepanovdb010da2012-12-26 09:32:05 +0000262
Alexey Samsonovc2918bf2013-06-27 07:50:56 +0000263// Unpoison first n function arguments.
264void UnpoisonParam(uptr n);
Evgeniy Stepanov91659d52013-08-27 12:59:39 +0000265void UnpoisonThreadLocalState();
Reid Kleckner0f92deb2013-03-11 18:07:42 +0000266
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700267// Returns a "chained" origin id, pointing to the given stack trace followed by
268// the previous origin id.
269u32 ChainOrigin(u32 id, StackTrace *stack);
270
Stephen Hines86277eb2015-03-23 12:06:32 -0700271const int STACK_TRACE_TAG_POISON = StackTrace::TAG_CUSTOM + 1;
272
Stephen Hines6d186232014-11-26 17:56:19 -0800273#define GET_MALLOC_STACK_TRACE \
274 BufferedStackTrace stack; \
275 if (__msan_get_track_origins() && msan_inited) \
276 GetStackTrace(&stack, common_flags()->malloc_context_size, \
277 StackTrace::GetCurrentPc(), GET_CURRENT_FRAME(), \
Stephen Hines6a211c52014-07-21 00:49:56 -0700278 common_flags()->fast_unwind_on_malloc)
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700279
Stephen Hines6d186232014-11-26 17:56:19 -0800280#define GET_STORE_STACK_TRACE_PC_BP(pc, bp) \
281 BufferedStackTrace stack; \
282 if (__msan_get_track_origins() > 1 && msan_inited) \
283 GetStackTrace(&stack, flags()->store_context_size, pc, bp, \
284 common_flags()->fast_unwind_on_malloc)
285
286#define GET_FATAL_STACK_TRACE_PC_BP(pc, bp) \
287 BufferedStackTrace stack; \
288 if (msan_inited) \
289 GetStackTrace(&stack, kStackTraceMax, pc, bp, \
290 common_flags()->fast_unwind_on_fatal)
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700291
292#define GET_STORE_STACK_TRACE \
293 GET_STORE_STACK_TRACE_PC_BP(StackTrace::GetCurrentPc(), GET_CURRENT_FRAME())
294
Evgeniy Stepanov0e38a672013-08-27 14:08:15 +0000295class ScopedThreadLocalStateBackup {
Alexey Samsonovc1548202013-08-28 11:26:09 +0000296 public:
Evgeniy Stepanov0e38a672013-08-27 14:08:15 +0000297 ScopedThreadLocalStateBackup() { Backup(); }
298 ~ScopedThreadLocalStateBackup() { Restore(); }
299 void Backup();
300 void Restore();
Alexey Samsonovc1548202013-08-28 11:26:09 +0000301 private:
Evgeniy Stepanov0e38a672013-08-27 14:08:15 +0000302 u64 va_arg_overflow_size_tls;
303};
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700304
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700305void MsanTSDInit(void (*destructor)(void *tsd));
306void *MsanTSDGet();
307void MsanTSDSet(void *tsd);
308void MsanTSDDtor(void *tsd);
309
Evgeniy Stepanov78c56c32012-12-11 12:27:27 +0000310} // namespace __msan
311
Evgeniy Stepanov5c48a8c2013-08-02 14:26:58 +0000312#define MSAN_MALLOC_HOOK(ptr, size) \
Stephen Hines6a211c52014-07-21 00:49:56 -0700313 if (&__sanitizer_malloc_hook) __sanitizer_malloc_hook(ptr, size)
Evgeniy Stepanov5c48a8c2013-08-02 14:26:58 +0000314#define MSAN_FREE_HOOK(ptr) \
Stephen Hines6a211c52014-07-21 00:49:56 -0700315 if (&__sanitizer_free_hook) __sanitizer_free_hook(ptr)
Evgeniy Stepanov5c48a8c2013-08-02 14:26:58 +0000316
Evgeniy Stepanov78c56c32012-12-11 12:27:27 +0000317#endif // MSAN_H