blob: 0adbeb68f67e7e37f2f56b6232542008374a31dc [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
55#elif SANITIZER_FREEBSD && SANITIZER_WORDSIZE == 64
56
57// Low memory: main binary, MAP_32BIT mappings and modules
58// High memory: heap, modules and main thread stack
59const MappingDesc kMemoryLayout[] = {
60 {0x000000000000ULL, 0x010000000000ULL, MappingDesc::APP, "low memory"},
61 {0x010000000000ULL, 0x100000000000ULL, MappingDesc::INVALID, "invalid"},
62 {0x100000000000ULL, 0x310000000000ULL, MappingDesc::SHADOW, "shadow"},
63 {0x310000000000ULL, 0x380000000000ULL, MappingDesc::INVALID, "invalid"},
64 {0x380000000000ULL, 0x590000000000ULL, MappingDesc::ORIGIN, "origin"},
65 {0x590000000000ULL, 0x600000000000ULL, MappingDesc::INVALID, "invalid"},
66 {0x600000000000ULL, 0x800000000000ULL, MappingDesc::APP, "high memory"}};
67
68// Maps low and high app ranges to contiguous space with zero base:
69// Low: 0000 0000 0000 - 00ff ffff ffff -> 2000 0000 0000 - 20ff ffff ffff
70// High: 6000 0000 0000 - 7fff ffff ffff -> 0000 0000 0000 - 1fff ffff ffff
71#define LINEARIZE_MEM(mem) \
72 (((uptr)(mem) & ~0xc00000000000ULL) ^ 0x200000000000ULL)
73#define MEM_TO_SHADOW(mem) (LINEARIZE_MEM((mem)) + 0x100000000000ULL)
74#define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x280000000000)
75
76#elif SANITIZER_LINUX && SANITIZER_WORDSIZE == 64
77
78// Requries PIE binary and ASLR enabled.
79// Main thread stack and DSOs at 0x7f0000000000 (sometimes 0x7e0000000000).
80// Heap at 0x600000000000.
81const MappingDesc kMemoryLayout[] = {
82 {0x000000000000ULL, 0x200000000000ULL, MappingDesc::INVALID, "invalid"},
83 {0x200000000000ULL, 0x400000000000ULL, MappingDesc::SHADOW, "shadow"},
84 {0x400000000000ULL, 0x600000000000ULL, MappingDesc::ORIGIN, "origin"},
85 {0x600000000000ULL, 0x800000000000ULL, MappingDesc::APP, "app"}};
86
87#define MEM_TO_SHADOW(mem) (((uptr)(mem)) & ~0x400000000000ULL)
88#define SHADOW_TO_ORIGIN(mem) (((uptr)(mem)) + 0x200000000000ULL)
89
90#else
91#error "Unsupported platform"
Stephen Hines6d186232014-11-26 17:56:19 -080092#endif
Evgeniy Stepanov78c56c32012-12-11 12:27:27 +000093
Stephen Hines86277eb2015-03-23 12:06:32 -070094const uptr kMemoryLayoutSize = sizeof(kMemoryLayout) / sizeof(kMemoryLayout[0]);
95
96#define MEM_TO_ORIGIN(mem) (SHADOW_TO_ORIGIN(MEM_TO_SHADOW((mem))))
97
98#ifndef __clang__
99__attribute__((optimize("unroll-loops")))
100#endif
101inline bool addr_is_type(uptr addr, MappingDesc::Type mapping_type) {
102// It is critical for performance that this loop is unrolled (because then it is
103// simplified into just a few constant comparisons).
104#ifdef __clang__
105#pragma unroll
106#endif
107 for (unsigned i = 0; i < kMemoryLayoutSize; ++i)
108 if (kMemoryLayout[i].type == mapping_type &&
109 addr >= kMemoryLayout[i].start && addr < kMemoryLayout[i].end)
110 return true;
111 return false;
112}
113
114#define MEM_IS_APP(mem) addr_is_type((uptr)(mem), MappingDesc::APP)
115#define MEM_IS_SHADOW(mem) addr_is_type((uptr)(mem), MappingDesc::SHADOW)
116#define MEM_IS_ORIGIN(mem) addr_is_type((uptr)(mem), MappingDesc::ORIGIN)
117
Stephen Hines6d186232014-11-26 17:56:19 -0800118// These constants must be kept in sync with the ones in MemorySanitizer.cc.
119const int kMsanParamTlsSize = 800;
120const int kMsanRetvalTlsSize = 800;
Evgeniy Stepanov78c56c32012-12-11 12:27:27 +0000121
122namespace __msan {
123extern int msan_inited;
124extern bool msan_init_is_running;
Evgeniy Stepanov99bf1d72013-01-10 11:17:55 +0000125extern int msan_report_count;
Evgeniy Stepanov78c56c32012-12-11 12:27:27 +0000126
127bool ProtectRange(uptr beg, uptr end);
Pirama Arumuga Nainarcdce50b2015-07-01 12:26:56 -0700128bool InitShadow(bool init_origins);
Evgeniy Stepanov78c56c32012-12-11 12:27:27 +0000129char *GetProcSelfMaps();
130void InitializeInterceptors();
131
Evgeniy Stepanov7c6bd402013-10-22 14:31:30 +0000132void MsanAllocatorThreadFinish();
Stephen Hines86277eb2015-03-23 12:06:32 -0700133void *MsanCalloc(StackTrace *stack, uptr nmemb, uptr size);
Evgeniy Stepanov78c56c32012-12-11 12:27:27 +0000134void *MsanReallocate(StackTrace *stack, void *oldp, uptr size,
135 uptr alignment, bool zeroise);
Evgeniy Stepanoveffdc7e2013-09-16 11:03:31 +0000136void MsanDeallocate(StackTrace *stack, void *ptr);
Evgeniy Stepanov78c56c32012-12-11 12:27:27 +0000137void InstallTrapHandler();
Evgeniy Stepanov99bf1d72013-01-10 11:17:55 +0000138void InstallAtExitHandler();
Evgeniy Stepanov78c56c32012-12-11 12:27:27 +0000139
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700140const char *GetStackOriginDescr(u32 id, uptr *pc);
Evgeniy Stepanov6f346052013-09-13 12:49:13 +0000141
Kostya Serebryany70c6e3f2013-02-13 07:19:47 +0000142void EnterSymbolizer();
143void ExitSymbolizer();
144bool IsInSymbolizer();
145
Reid Kleckner93c26022013-03-06 16:11:58 +0000146struct SymbolizerScope {
147 SymbolizerScope() { EnterSymbolizer(); }
148 ~SymbolizerScope() { ExitSymbolizer(); }
149};
150
Evgeniy Stepanov78c56c32012-12-11 12:27:27 +0000151void MsanDie();
152void PrintWarning(uptr pc, uptr bp);
153void PrintWarningWithOrigin(uptr pc, uptr bp, u32 origin);
154
Stephen Hines6d186232014-11-26 17:56:19 -0800155void GetStackTrace(BufferedStackTrace *stack, uptr max_s, uptr pc, uptr bp,
Alexey Samsonovf16dc422013-11-07 07:28:33 +0000156 bool request_fast_unwind);
Evgeniy Stepanov78c56c32012-12-11 12:27:27 +0000157
Evgeniy Stepanovdb010da2012-12-26 09:32:05 +0000158void ReportUMR(StackTrace *stack, u32 origin);
159void ReportExpectedUMRNotFound(StackTrace *stack);
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700160void ReportStats();
Evgeniy Stepanov99bf1d72013-01-10 11:17:55 +0000161void ReportAtExitStatistics();
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700162void DescribeMemoryRange(const void *x, uptr size);
163void ReportUMRInsideAddressRange(const char *what, const void *start, uptr size,
164 uptr offset);
Evgeniy Stepanovdb010da2012-12-26 09:32:05 +0000165
Alexey Samsonovc2918bf2013-06-27 07:50:56 +0000166// Unpoison first n function arguments.
167void UnpoisonParam(uptr n);
Evgeniy Stepanov91659d52013-08-27 12:59:39 +0000168void UnpoisonThreadLocalState();
Reid Kleckner0f92deb2013-03-11 18:07:42 +0000169
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700170// Returns a "chained" origin id, pointing to the given stack trace followed by
171// the previous origin id.
172u32 ChainOrigin(u32 id, StackTrace *stack);
173
Stephen Hines86277eb2015-03-23 12:06:32 -0700174const int STACK_TRACE_TAG_POISON = StackTrace::TAG_CUSTOM + 1;
175
Stephen Hines6d186232014-11-26 17:56:19 -0800176#define GET_MALLOC_STACK_TRACE \
177 BufferedStackTrace stack; \
178 if (__msan_get_track_origins() && msan_inited) \
179 GetStackTrace(&stack, common_flags()->malloc_context_size, \
180 StackTrace::GetCurrentPc(), GET_CURRENT_FRAME(), \
Stephen Hines6a211c52014-07-21 00:49:56 -0700181 common_flags()->fast_unwind_on_malloc)
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700182
Stephen Hines6d186232014-11-26 17:56:19 -0800183#define GET_STORE_STACK_TRACE_PC_BP(pc, bp) \
184 BufferedStackTrace stack; \
185 if (__msan_get_track_origins() > 1 && msan_inited) \
186 GetStackTrace(&stack, flags()->store_context_size, pc, bp, \
187 common_flags()->fast_unwind_on_malloc)
188
189#define GET_FATAL_STACK_TRACE_PC_BP(pc, bp) \
190 BufferedStackTrace stack; \
191 if (msan_inited) \
192 GetStackTrace(&stack, kStackTraceMax, pc, bp, \
193 common_flags()->fast_unwind_on_fatal)
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700194
195#define GET_STORE_STACK_TRACE \
196 GET_STORE_STACK_TRACE_PC_BP(StackTrace::GetCurrentPc(), GET_CURRENT_FRAME())
197
Evgeniy Stepanov0e38a672013-08-27 14:08:15 +0000198class ScopedThreadLocalStateBackup {
Alexey Samsonovc1548202013-08-28 11:26:09 +0000199 public:
Evgeniy Stepanov0e38a672013-08-27 14:08:15 +0000200 ScopedThreadLocalStateBackup() { Backup(); }
201 ~ScopedThreadLocalStateBackup() { Restore(); }
202 void Backup();
203 void Restore();
Alexey Samsonovc1548202013-08-28 11:26:09 +0000204 private:
Evgeniy Stepanov0e38a672013-08-27 14:08:15 +0000205 u64 va_arg_overflow_size_tls;
206};
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700207
208extern void (*death_callback)(void);
209
210void MsanTSDInit(void (*destructor)(void *tsd));
211void *MsanTSDGet();
212void MsanTSDSet(void *tsd);
213void MsanTSDDtor(void *tsd);
214
Evgeniy Stepanov78c56c32012-12-11 12:27:27 +0000215} // namespace __msan
216
Evgeniy Stepanov5c48a8c2013-08-02 14:26:58 +0000217#define MSAN_MALLOC_HOOK(ptr, size) \
Stephen Hines6a211c52014-07-21 00:49:56 -0700218 if (&__sanitizer_malloc_hook) __sanitizer_malloc_hook(ptr, size)
Evgeniy Stepanov5c48a8c2013-08-02 14:26:58 +0000219#define MSAN_FREE_HOOK(ptr) \
Stephen Hines6a211c52014-07-21 00:49:56 -0700220 if (&__sanitizer_free_hook) __sanitizer_free_hook(ptr)
Evgeniy Stepanov5c48a8c2013-08-02 14:26:58 +0000221
Evgeniy Stepanov78c56c32012-12-11 12:27:27 +0000222#endif // MSAN_H