blob: 3776fa9cede80625f8cba95fc6d7d2170d44a40b [file] [log] [blame]
Evgeniy Stepanov67227162012-12-25 11:53:51 +00001//===-- msan.h --------------------------------------------------*- C++ -*-===//
Evgeniy Stepanovc5033782012-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 Matveev6eff11e2013-05-06 13:15:14 +000018#include "sanitizer_common/sanitizer_flags.h"
Evgeniy Stepanovc5033782012-12-11 12:27:27 +000019#include "sanitizer_common/sanitizer_internal_defs.h"
20#include "sanitizer_common/sanitizer_stacktrace.h"
Evgeniy Stepanoveac7f932013-01-29 14:33:29 +000021#include "msan_interface_internal.h"
Evgeniy Stepanovc5033782012-12-11 12:27:27 +000022#include "msan_flags.h"
Alexey Samsonovb3053d92015-04-28 00:56:48 +000023#include "ubsan/ubsan_platform.h"
Evgeniy Stepanovc5033782012-12-11 12:27:27 +000024
Evgeniy Stepanovc7af8782013-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
Alexey Samsonovb3053d92015-04-28 00:56:48 +000029#ifndef MSAN_CONTAINS_UBSAN
30# define MSAN_CONTAINS_UBSAN CAN_SANITIZE_UB
31#endif
32
Evgeniy Stepanov8441bb22015-01-27 13:20:34 +000033struct MappingDesc {
34 uptr start;
35 uptr end;
36 enum Type {
37 INVALID, APP, SHADOW, ORIGIN
38 } type;
39 const char *name;
40};
Viktor Kutuzov30bd3452014-11-28 11:42:55 +000041
Viktor Kutuzov30bd3452014-11-28 11:42:55 +000042
43#if SANITIZER_LINUX && defined(__mips64)
Evgeniy Stepanov8441bb22015-01-27 13:20:34 +000044
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
Adhemerval Zanella19074452015-09-16 15:12:25 +000055#elif SANITIZER_LINUX && defined(__aarch64__)
56
57# if SANITIZER_AARCH64_VMA == 39
58const MappingDesc kMemoryLayout[] = {
59 {0x0000000000ULL, 0x4000000000ULL, MappingDesc::INVALID, "invalid"},
60 {0x4000000000ULL, 0x4300000000ULL, MappingDesc::SHADOW, "shadow"},
61 {0x4300000000ULL, 0x4600000000ULL, MappingDesc::ORIGIN, "origin"},
62 {0x4600000000ULL, 0x5500000000ULL, MappingDesc::INVALID, "invalid"},
63 {0x5500000000ULL, 0x5600000000ULL, MappingDesc::APP, "app"},
64 {0x5600000000ULL, 0x7000000000ULL, MappingDesc::INVALID, "invalid"},
65 {0x7000000000ULL, 0x8000000000ULL, MappingDesc::APP, "app"}
66};
67// Maps low and high app ranges to contiguous space with zero base:
68// Low: 55 0000 0000 - 55 ffff ffff -> 1 0000 0000 - 1 ffff ffff
69// High: 70 0000 0000 - 7f ffff ffff -> 0 0000 0000 - f ffff ffff
70# define LINEARIZE_MEM(mem) \
71 (((uptr)(mem) & ~0x7C00000000ULL) ^ 0x100000000ULL)
72# define MEM_TO_SHADOW(mem) (LINEARIZE_MEM((mem)) + 0x4000000000ULL)
73# define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x300000000ULL)
74
75# elif SANITIZER_AARCH64_VMA == 42
76const MappingDesc kMemoryLayout[] = {
77 {0x00000000000ULL, 0x10000000000ULL, MappingDesc::INVALID, "invalid"},
78 {0x10000000000ULL, 0x11b00000000ULL, MappingDesc::SHADOW, "shadow"},
79 {0x11b00000000ULL, 0x12000000000ULL, MappingDesc::INVALID, "invalid"},
80 {0x12000000000ULL, 0x13b00000000ULL, MappingDesc::ORIGIN, "origin"},
81 {0x13b00000000ULL, 0x2aa00000000ULL, MappingDesc::INVALID, "invalid"},
82 {0x2aa00000000ULL, 0x2ab00000000ULL, MappingDesc::APP, "app"},
83 {0x2ab00000000ULL, 0x3f000000000ULL, MappingDesc::INVALID, "invalid"},
84 {0x3f000000000ULL, 0x40000000000ULL, MappingDesc::APP, "app"},
85};
86// Maps low and high app ranges to contigous space with zero base:
87// 2 aa00 0000 00 - 2 ab00 0000 00: -> 1a00 0000 00 - 1aff ffff ff
88// 3 f000 0000 00 - 4 0000 0000 00: -> 0000 0000 00 - 0fff ffff ff
89# define LINEARIZE_MEM(mem) \
90 (((uptr)(mem) & ~0x3E000000000ULL) ^ 0x1000000000ULL)
91# define MEM_TO_SHADOW(mem) (LINEARIZE_MEM((mem)) + 0x10000000000ULL)
92# define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x2000000000ULL)
93
94# endif // SANITIZER_AARCH64_VMA
95
Jay Foad8677baf2015-06-25 06:22:31 +000096#elif SANITIZER_LINUX && defined(__powerpc64__)
97
98const MappingDesc kMemoryLayout[] = {
99 {0x000000000000ULL, 0x000100000000ULL, MappingDesc::APP, "low memory"},
100 {0x000100000000ULL, 0x080000000000ULL, MappingDesc::INVALID, "invalid"},
101 {0x080000000000ULL, 0x180100000000ULL, MappingDesc::SHADOW, "shadow"},
102 {0x180100000000ULL, 0x1C0000000000ULL, MappingDesc::INVALID, "invalid"},
103 {0x1C0000000000ULL, 0x2C0100000000ULL, MappingDesc::ORIGIN, "origin"},
104 {0x2C0100000000ULL, 0x300000000000ULL, MappingDesc::INVALID, "invalid"},
105 {0x300000000000ULL, 0x400000000000ULL, MappingDesc::APP, "high memory"}};
106
107// Maps low and high app ranges to contiguous space with zero base:
108// Low: 0000 0000 0000 - 0000 ffff ffff -> 1000 0000 0000 - 1000 ffff ffff
109// High: 3000 0000 0000 - 3fff ffff ffff -> 0000 0000 0000 - 0fff ffff ffff
110#define LINEARIZE_MEM(mem) \
111 (((uptr)(mem) & ~0x200000000000ULL) ^ 0x100000000000ULL)
112#define MEM_TO_SHADOW(mem) (LINEARIZE_MEM((mem)) + 0x080000000000ULL)
113#define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x140000000000ULL)
114
Viktor Kutuzov30bd3452014-11-28 11:42:55 +0000115#elif SANITIZER_FREEBSD && SANITIZER_WORDSIZE == 64
Evgeniy Stepanov8441bb22015-01-27 13:20:34 +0000116
117// Low memory: main binary, MAP_32BIT mappings and modules
118// High memory: heap, modules and main thread stack
119const MappingDesc kMemoryLayout[] = {
120 {0x000000000000ULL, 0x010000000000ULL, MappingDesc::APP, "low memory"},
121 {0x010000000000ULL, 0x100000000000ULL, MappingDesc::INVALID, "invalid"},
122 {0x100000000000ULL, 0x310000000000ULL, MappingDesc::SHADOW, "shadow"},
123 {0x310000000000ULL, 0x380000000000ULL, MappingDesc::INVALID, "invalid"},
124 {0x380000000000ULL, 0x590000000000ULL, MappingDesc::ORIGIN, "origin"},
125 {0x590000000000ULL, 0x600000000000ULL, MappingDesc::INVALID, "invalid"},
126 {0x600000000000ULL, 0x800000000000ULL, MappingDesc::APP, "high memory"}};
127
Viktor Kutuzov30bd3452014-11-28 11:42:55 +0000128// Maps low and high app ranges to contiguous space with zero base:
129// Low: 0000 0000 0000 - 00ff ffff ffff -> 2000 0000 0000 - 20ff ffff ffff
130// High: 6000 0000 0000 - 7fff ffff ffff -> 0000 0000 0000 - 1fff ffff ffff
Evgeniy Stepanov8441bb22015-01-27 13:20:34 +0000131#define LINEARIZE_MEM(mem) \
132 (((uptr)(mem) & ~0xc00000000000ULL) ^ 0x200000000000ULL)
133#define MEM_TO_SHADOW(mem) (LINEARIZE_MEM((mem)) + 0x100000000000ULL)
134#define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x280000000000)
135
Viktor Kutuzov30bd3452014-11-28 11:42:55 +0000136#elif SANITIZER_LINUX && SANITIZER_WORDSIZE == 64
Evgeniy Stepanov8441bb22015-01-27 13:20:34 +0000137
138// Requries PIE binary and ASLR enabled.
139// Main thread stack and DSOs at 0x7f0000000000 (sometimes 0x7e0000000000).
140// Heap at 0x600000000000.
141const MappingDesc kMemoryLayout[] = {
142 {0x000000000000ULL, 0x200000000000ULL, MappingDesc::INVALID, "invalid"},
143 {0x200000000000ULL, 0x400000000000ULL, MappingDesc::SHADOW, "shadow"},
144 {0x400000000000ULL, 0x600000000000ULL, MappingDesc::ORIGIN, "origin"},
145 {0x600000000000ULL, 0x800000000000ULL, MappingDesc::APP, "app"}};
146
147#define MEM_TO_SHADOW(mem) (((uptr)(mem)) & ~0x400000000000ULL)
148#define SHADOW_TO_ORIGIN(mem) (((uptr)(mem)) + 0x200000000000ULL)
149
Viktor Kutuzov30bd3452014-11-28 11:42:55 +0000150#else
151#error "Unsupported platform"
Alexey Samsonovde130182014-11-19 21:42:33 +0000152#endif
Evgeniy Stepanovc5033782012-12-11 12:27:27 +0000153
Evgeniy Stepanov8441bb22015-01-27 13:20:34 +0000154const uptr kMemoryLayoutSize = sizeof(kMemoryLayout) / sizeof(kMemoryLayout[0]);
Viktor Kutuzov30bd3452014-11-28 11:42:55 +0000155
156#define MEM_TO_ORIGIN(mem) (SHADOW_TO_ORIGIN(MEM_TO_SHADOW((mem))))
157
Evgeniy Stepanov8441bb22015-01-27 13:20:34 +0000158#ifndef __clang__
159__attribute__((optimize("unroll-loops")))
160#endif
161inline bool addr_is_type(uptr addr, MappingDesc::Type mapping_type) {
162// It is critical for performance that this loop is unrolled (because then it is
163// simplified into just a few constant comparisons).
164#ifdef __clang__
165#pragma unroll
166#endif
167 for (unsigned i = 0; i < kMemoryLayoutSize; ++i)
168 if (kMemoryLayout[i].type == mapping_type &&
169 addr >= kMemoryLayout[i].start && addr < kMemoryLayout[i].end)
170 return true;
171 return false;
172}
Viktor Kutuzov30bd3452014-11-28 11:42:55 +0000173
Evgeniy Stepanov8441bb22015-01-27 13:20:34 +0000174#define MEM_IS_APP(mem) addr_is_type((uptr)(mem), MappingDesc::APP)
175#define MEM_IS_SHADOW(mem) addr_is_type((uptr)(mem), MappingDesc::SHADOW)
176#define MEM_IS_ORIGIN(mem) addr_is_type((uptr)(mem), MappingDesc::ORIGIN)
Viktor Kutuzov30bd3452014-11-28 11:42:55 +0000177
Evgeniy Stepanov35eb2652014-10-22 00:12:40 +0000178// These constants must be kept in sync with the ones in MemorySanitizer.cc.
179const int kMsanParamTlsSize = 800;
180const int kMsanRetvalTlsSize = 800;
Evgeniy Stepanovc5033782012-12-11 12:27:27 +0000181
182namespace __msan {
183extern int msan_inited;
184extern bool msan_init_is_running;
Evgeniy Stepanov9b52ce92013-01-10 11:17:55 +0000185extern int msan_report_count;
Evgeniy Stepanovc5033782012-12-11 12:27:27 +0000186
187bool ProtectRange(uptr beg, uptr end);
Evgeniy Stepanov45328242015-05-24 02:47:59 +0000188bool InitShadow(bool init_origins);
Evgeniy Stepanovc5033782012-12-11 12:27:27 +0000189char *GetProcSelfMaps();
190void InitializeInterceptors();
191
Evgeniy Stepanov7aba3962015-09-29 21:28:54 +0000192void MsanAllocatorInit();
Evgeniy Stepanov2794c472013-10-22 14:31:30 +0000193void MsanAllocatorThreadFinish();
Alexey Samsonov6334f462014-12-12 20:07:35 +0000194void *MsanCalloc(StackTrace *stack, uptr nmemb, uptr size);
Evgeniy Stepanovc5033782012-12-11 12:27:27 +0000195void *MsanReallocate(StackTrace *stack, void *oldp, uptr size,
196 uptr alignment, bool zeroise);
Evgeniy Stepanov65562f52013-09-16 11:03:31 +0000197void MsanDeallocate(StackTrace *stack, void *ptr);
Evgeniy Stepanovc5033782012-12-11 12:27:27 +0000198void InstallTrapHandler();
Evgeniy Stepanov9b52ce92013-01-10 11:17:55 +0000199void InstallAtExitHandler();
Evgeniy Stepanovc5033782012-12-11 12:27:27 +0000200
Evgeniy Stepanov208aae82014-05-21 09:02:13 +0000201const char *GetStackOriginDescr(u32 id, uptr *pc);
Evgeniy Stepanovac5ac342013-09-13 12:49:13 +0000202
Kostya Serebryanyec87e782013-02-13 07:19:47 +0000203void EnterSymbolizer();
204void ExitSymbolizer();
205bool IsInSymbolizer();
206
Reid Kleckner063dfe32013-03-06 16:11:58 +0000207struct SymbolizerScope {
208 SymbolizerScope() { EnterSymbolizer(); }
209 ~SymbolizerScope() { ExitSymbolizer(); }
210};
211
Evgeniy Stepanovc5033782012-12-11 12:27:27 +0000212void PrintWarning(uptr pc, uptr bp);
213void PrintWarningWithOrigin(uptr pc, uptr bp, u32 origin);
214
Alexey Samsonov9c859272014-10-26 03:35:14 +0000215void GetStackTrace(BufferedStackTrace *stack, uptr max_s, uptr pc, uptr bp,
Alexey Samsonovb3d93992013-11-07 07:28:33 +0000216 bool request_fast_unwind);
Evgeniy Stepanovc5033782012-12-11 12:27:27 +0000217
Evgeniy Stepanov367dc642012-12-26 09:32:05 +0000218void ReportUMR(StackTrace *stack, u32 origin);
219void ReportExpectedUMRNotFound(StackTrace *stack);
Evgeniy Stepanovbce21ac2014-05-21 09:56:28 +0000220void ReportStats();
Evgeniy Stepanov9b52ce92013-01-10 11:17:55 +0000221void ReportAtExitStatistics();
Evgeniy Stepanovfe250b02014-04-30 09:50:30 +0000222void DescribeMemoryRange(const void *x, uptr size);
Evgeniy Stepanov8dd62dc2014-05-07 11:50:14 +0000223void ReportUMRInsideAddressRange(const char *what, const void *start, uptr size,
224 uptr offset);
Evgeniy Stepanov367dc642012-12-26 09:32:05 +0000225
Alexey Samsonoved4594b2013-06-27 07:50:56 +0000226// Unpoison first n function arguments.
227void UnpoisonParam(uptr n);
Evgeniy Stepanovc4179812013-08-27 12:59:39 +0000228void UnpoisonThreadLocalState();
Reid Klecknerc9d382b2013-03-11 18:07:42 +0000229
Evgeniy Stepanov412d9732014-03-18 13:45:19 +0000230// Returns a "chained" origin id, pointing to the given stack trace followed by
231// the previous origin id.
232u32 ChainOrigin(u32 id, StackTrace *stack);
233
Evgeniy Stepanovd38af302015-01-22 13:33:16 +0000234const int STACK_TRACE_TAG_POISON = StackTrace::TAG_CUSTOM + 1;
235
Alexey Samsonov9c859272014-10-26 03:35:14 +0000236#define GET_MALLOC_STACK_TRACE \
237 BufferedStackTrace stack; \
238 if (__msan_get_track_origins() && msan_inited) \
239 GetStackTrace(&stack, common_flags()->malloc_context_size, \
240 StackTrace::GetCurrentPc(), GET_CURRENT_FRAME(), \
Evgeniy Stepanovc935ca82014-06-27 12:48:01 +0000241 common_flags()->fast_unwind_on_malloc)
Evgeniy Stepanov3c957442014-03-31 14:18:55 +0000242
Alexey Samsonov9c859272014-10-26 03:35:14 +0000243#define GET_STORE_STACK_TRACE_PC_BP(pc, bp) \
244 BufferedStackTrace stack; \
245 if (__msan_get_track_origins() > 1 && msan_inited) \
246 GetStackTrace(&stack, flags()->store_context_size, pc, bp, \
247 common_flags()->fast_unwind_on_malloc)
248
249#define GET_FATAL_STACK_TRACE_PC_BP(pc, bp) \
250 BufferedStackTrace stack; \
251 if (msan_inited) \
252 GetStackTrace(&stack, kStackTraceMax, pc, bp, \
253 common_flags()->fast_unwind_on_fatal)
Sergey Matveeva5310582014-05-26 13:08:08 +0000254
Evgeniy Stepanov3c957442014-03-31 14:18:55 +0000255#define GET_STORE_STACK_TRACE \
256 GET_STORE_STACK_TRACE_PC_BP(StackTrace::GetCurrentPc(), GET_CURRENT_FRAME())
Evgeniy Stepanov412d9732014-03-18 13:45:19 +0000257
Evgeniy Stepanovcb22c672013-08-27 14:08:15 +0000258class ScopedThreadLocalStateBackup {
Alexey Samsonovef643ce2013-08-28 11:26:09 +0000259 public:
Evgeniy Stepanovcb22c672013-08-27 14:08:15 +0000260 ScopedThreadLocalStateBackup() { Backup(); }
261 ~ScopedThreadLocalStateBackup() { Restore(); }
262 void Backup();
263 void Restore();
Alexey Samsonovef643ce2013-08-28 11:26:09 +0000264 private:
Evgeniy Stepanovcb22c672013-08-27 14:08:15 +0000265 u64 va_arg_overflow_size_tls;
266};
Evgeniy Stepanov89602652014-03-27 14:04:58 +0000267
Evgeniy Stepanovf653cda2014-04-04 09:47:41 +0000268void MsanTSDInit(void (*destructor)(void *tsd));
269void *MsanTSDGet();
270void MsanTSDSet(void *tsd);
271void MsanTSDDtor(void *tsd);
272
Evgeniy Stepanovc5033782012-12-11 12:27:27 +0000273} // namespace __msan
274
Evgeniy Stepanov44b77c22013-08-02 14:26:58 +0000275#define MSAN_MALLOC_HOOK(ptr, size) \
Alexey Samsonov91bb8e02014-07-07 17:39:31 +0000276 if (&__sanitizer_malloc_hook) __sanitizer_malloc_hook(ptr, size)
Evgeniy Stepanov44b77c22013-08-02 14:26:58 +0000277#define MSAN_FREE_HOOK(ptr) \
Alexey Samsonov91bb8e02014-07-07 17:39:31 +0000278 if (&__sanitizer_free_hook) __sanitizer_free_hook(ptr)
Evgeniy Stepanov44b77c22013-08-02 14:26:58 +0000279
Evgeniy Stepanovc5033782012-12-11 12:27:27 +0000280#endif // MSAN_H