blob: 9bc1e4c6a4473d93970787c67e8095d4acf99223 [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"
23
Evgeniy Stepanovc7af8782013-04-05 12:03:47 +000024#ifndef MSAN_REPLACE_OPERATORS_NEW_AND_DELETE
25# define MSAN_REPLACE_OPERATORS_NEW_AND_DELETE 1
26#endif
27
Viktor Kutuzov30bd3452014-11-28 11:42:55 +000028/*
29C/C++ on FreeBSD
300000 0000 0000 - 00ff ffff ffff: Low memory: main binary, MAP_32BIT mappings and modules
310100 0000 0000 - 0fff ffff ffff: Bad1
321000 0000 0000 - 30ff ffff ffff: Shadow
333100 0000 0000 - 37ff ffff ffff: Bad2
343800 0000 0000 - 58ff ffff ffff: Origins
355900 0000 0000 - 5fff ffff ffff: Bad3
366000 0000 0000 - 7fff ffff ffff: High memory: heap, modules and main thread stack
37
38C/C++ on Linux/PIE
390000 0000 0000 - 1fff ffff ffff: Bad1
402000 0000 0000 - 3fff ffff ffff: Shadow
414000 0000 0000 - 5fff ffff ffff: Origins
426000 0000 0000 - 7fff ffff ffff: Main memory
43
44C/C++ on Mips
450000 0000 0000 - 009f ffff ffff: Bad1
4600a0 0000 0000 - 00bf ffff ffff: Shadow
4700c0 0000 0000 - 00df ffff ffff: Origins
4800e0 0000 0000 - 00ff ffff ffff: Main memory
49*/
50
51#if SANITIZER_LINUX && defined(__mips64)
52const uptr kLowMemBeg = 0;
53const uptr kLowMemSize = 0;
54const uptr kHighMemBeg = 0x00e000000000;
55const uptr kHighMemSize = 0x002000000000;
56const uptr kShadowBeg = 0x00a000000000;
57const uptr kShadowSize = 0x002000000000;
58const uptr kOriginsBeg = 0x00c000000000;
59# define MEM_TO_SHADOW(mem) (((uptr)(mem)) & ~0x4000000000ULL)
60#elif SANITIZER_FREEBSD && SANITIZER_WORDSIZE == 64
61const uptr kLowMemBeg = 0x000000000000;
62const uptr kLowMemSize = 0x010000000000;
63const uptr kHighMemBeg = 0x600000000000;
64const uptr kHighMemSize = 0x200000000000;
65const uptr kShadowBeg = 0x100000000000;
66const uptr kShadowSize = 0x210000000000;
67const uptr kOriginsBeg = 0x380000000000;
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#elif SANITIZER_LINUX && SANITIZER_WORDSIZE == 64
75const uptr kLowMemBeg = 0;
76const uptr kLowMemSize = 0;
77const uptr kHighMemBeg = 0x600000000000;
78const uptr kHighMemSize = 0x200000000000;
79const uptr kShadowBeg = 0x200000000000;
80const uptr kShadowSize = 0x200000000000;
81const uptr kOriginsBeg = 0x400000000000;
82# define MEM_TO_SHADOW(mem) (((uptr)(mem)) & ~0x400000000000ULL)
83#else
84#error "Unsupported platform"
Alexey Samsonovde130182014-11-19 21:42:33 +000085#endif
Evgeniy Stepanovc5033782012-12-11 12:27:27 +000086
Viktor Kutuzov30bd3452014-11-28 11:42:55 +000087const uptr kBad1Beg = kLowMemBeg + kLowMemSize;
88const uptr kBad1Size = kShadowBeg - kBad1Beg;
89
90const uptr kBad2Beg = kShadowBeg + kShadowSize;
91const uptr kBad2Size = kOriginsBeg - kBad2Beg;
92
93const uptr kOriginsSize = kShadowSize;
94
95const uptr kBad3Beg = kOriginsBeg + kOriginsSize;
96const uptr kBad3Size = kHighMemBeg - kBad3Beg;
97
98#define SHADOW_TO_ORIGIN(shadow) \
99 (((uptr)(shadow)) + (kOriginsBeg - kShadowBeg))
100
101#define MEM_TO_ORIGIN(mem) (SHADOW_TO_ORIGIN(MEM_TO_SHADOW((mem))))
102
103#define MEM_IS_APP(mem) \
104 ((kLowMemSize > 0 && (uptr)(mem) < kLowMemSize) || \
105 (uptr)(mem) >= kHighMemBeg)
106
107#define MEM_IS_SHADOW(mem) \
108 ((uptr)(mem) >= kShadowBeg && (uptr)(mem) < kShadowBeg + kShadowSize)
109
110#define MEM_IS_ORIGIN(mem) \
111 ((uptr)(mem) >= kOriginsBeg && (uptr)(mem) < kOriginsBeg + kOriginsSize)
112
Evgeniy Stepanov35eb2652014-10-22 00:12:40 +0000113// These constants must be kept in sync with the ones in MemorySanitizer.cc.
114const int kMsanParamTlsSize = 800;
115const int kMsanRetvalTlsSize = 800;
Evgeniy Stepanovc5033782012-12-11 12:27:27 +0000116
117namespace __msan {
118extern int msan_inited;
119extern bool msan_init_is_running;
Evgeniy Stepanov9b52ce92013-01-10 11:17:55 +0000120extern int msan_report_count;
Evgeniy Stepanovc5033782012-12-11 12:27:27 +0000121
122bool ProtectRange(uptr beg, uptr end);
Viktor Kutuzov30bd3452014-11-28 11:42:55 +0000123bool InitShadow(bool map_shadow, bool init_origins);
Evgeniy Stepanovc5033782012-12-11 12:27:27 +0000124char *GetProcSelfMaps();
125void InitializeInterceptors();
126
Evgeniy Stepanov2794c472013-10-22 14:31:30 +0000127void MsanAllocatorThreadFinish();
Evgeniy Stepanovc5033782012-12-11 12:27:27 +0000128void *MsanReallocate(StackTrace *stack, void *oldp, uptr size,
129 uptr alignment, bool zeroise);
Evgeniy Stepanov65562f52013-09-16 11:03:31 +0000130void MsanDeallocate(StackTrace *stack, void *ptr);
Evgeniy Stepanovc5033782012-12-11 12:27:27 +0000131void InstallTrapHandler();
Evgeniy Stepanov9b52ce92013-01-10 11:17:55 +0000132void InstallAtExitHandler();
Evgeniy Stepanovc5033782012-12-11 12:27:27 +0000133void ReplaceOperatorsNewAndDelete();
134
Evgeniy Stepanov208aae82014-05-21 09:02:13 +0000135const char *GetStackOriginDescr(u32 id, uptr *pc);
Evgeniy Stepanovac5ac342013-09-13 12:49:13 +0000136
Kostya Serebryanyec87e782013-02-13 07:19:47 +0000137void EnterSymbolizer();
138void ExitSymbolizer();
139bool IsInSymbolizer();
140
Reid Kleckner063dfe32013-03-06 16:11:58 +0000141struct SymbolizerScope {
142 SymbolizerScope() { EnterSymbolizer(); }
143 ~SymbolizerScope() { ExitSymbolizer(); }
144};
145
Evgeniy Stepanovc5033782012-12-11 12:27:27 +0000146void MsanDie();
147void PrintWarning(uptr pc, uptr bp);
148void PrintWarningWithOrigin(uptr pc, uptr bp, u32 origin);
149
Alexey Samsonov9c859272014-10-26 03:35:14 +0000150void GetStackTrace(BufferedStackTrace *stack, uptr max_s, uptr pc, uptr bp,
Alexey Samsonovb3d93992013-11-07 07:28:33 +0000151 bool request_fast_unwind);
Evgeniy Stepanovc5033782012-12-11 12:27:27 +0000152
Evgeniy Stepanov367dc642012-12-26 09:32:05 +0000153void ReportUMR(StackTrace *stack, u32 origin);
154void ReportExpectedUMRNotFound(StackTrace *stack);
Evgeniy Stepanovbce21ac2014-05-21 09:56:28 +0000155void ReportStats();
Evgeniy Stepanov9b52ce92013-01-10 11:17:55 +0000156void ReportAtExitStatistics();
Evgeniy Stepanovfe250b02014-04-30 09:50:30 +0000157void DescribeMemoryRange(const void *x, uptr size);
Evgeniy Stepanov8dd62dc2014-05-07 11:50:14 +0000158void ReportUMRInsideAddressRange(const char *what, const void *start, uptr size,
159 uptr offset);
Evgeniy Stepanov367dc642012-12-26 09:32:05 +0000160
Alexey Samsonoved4594b2013-06-27 07:50:56 +0000161// Unpoison first n function arguments.
162void UnpoisonParam(uptr n);
Evgeniy Stepanovc4179812013-08-27 12:59:39 +0000163void UnpoisonThreadLocalState();
Reid Klecknerc9d382b2013-03-11 18:07:42 +0000164
Evgeniy Stepanova55fcd32014-04-02 11:06:35 +0000165u32 GetOriginIfPoisoned(uptr a, uptr size);
166void SetOriginIfPoisoned(uptr addr, uptr src_shadow, uptr size, u32 src_origin);
Evgeniy Stepanov412d9732014-03-18 13:45:19 +0000167void CopyOrigin(void *dst, const void *src, uptr size, StackTrace *stack);
168void MovePoison(void *dst, const void *src, uptr size, StackTrace *stack);
169void CopyPoison(void *dst, const void *src, uptr size, StackTrace *stack);
170
171// Returns a "chained" origin id, pointing to the given stack trace followed by
172// the previous origin id.
173u32 ChainOrigin(u32 id, StackTrace *stack);
174
Alexey Samsonov9c859272014-10-26 03:35:14 +0000175#define GET_MALLOC_STACK_TRACE \
176 BufferedStackTrace stack; \
177 if (__msan_get_track_origins() && msan_inited) \
178 GetStackTrace(&stack, common_flags()->malloc_context_size, \
179 StackTrace::GetCurrentPc(), GET_CURRENT_FRAME(), \
Evgeniy Stepanovc935ca82014-06-27 12:48:01 +0000180 common_flags()->fast_unwind_on_malloc)
Evgeniy Stepanov3c957442014-03-31 14:18:55 +0000181
Alexey Samsonov9c859272014-10-26 03:35:14 +0000182#define GET_STORE_STACK_TRACE_PC_BP(pc, bp) \
183 BufferedStackTrace stack; \
184 if (__msan_get_track_origins() > 1 && msan_inited) \
185 GetStackTrace(&stack, flags()->store_context_size, pc, bp, \
186 common_flags()->fast_unwind_on_malloc)
187
188#define GET_FATAL_STACK_TRACE_PC_BP(pc, bp) \
189 BufferedStackTrace stack; \
190 if (msan_inited) \
191 GetStackTrace(&stack, kStackTraceMax, pc, bp, \
192 common_flags()->fast_unwind_on_fatal)
Sergey Matveeva5310582014-05-26 13:08:08 +0000193
Evgeniy Stepanov3c957442014-03-31 14:18:55 +0000194#define GET_STORE_STACK_TRACE \
195 GET_STORE_STACK_TRACE_PC_BP(StackTrace::GetCurrentPc(), GET_CURRENT_FRAME())
Evgeniy Stepanov412d9732014-03-18 13:45:19 +0000196
Evgeniy Stepanovcb22c672013-08-27 14:08:15 +0000197class ScopedThreadLocalStateBackup {
Alexey Samsonovef643ce2013-08-28 11:26:09 +0000198 public:
Evgeniy Stepanovcb22c672013-08-27 14:08:15 +0000199 ScopedThreadLocalStateBackup() { Backup(); }
200 ~ScopedThreadLocalStateBackup() { Restore(); }
201 void Backup();
202 void Restore();
Alexey Samsonovef643ce2013-08-28 11:26:09 +0000203 private:
Evgeniy Stepanovcb22c672013-08-27 14:08:15 +0000204 u64 va_arg_overflow_size_tls;
205};
Evgeniy Stepanov89602652014-03-27 14:04:58 +0000206
207extern void (*death_callback)(void);
208
Evgeniy Stepanovf653cda2014-04-04 09:47:41 +0000209void MsanTSDInit(void (*destructor)(void *tsd));
210void *MsanTSDGet();
211void MsanTSDSet(void *tsd);
212void MsanTSDDtor(void *tsd);
213
Evgeniy Stepanovc5033782012-12-11 12:27:27 +0000214} // namespace __msan
215
Evgeniy Stepanov44b77c22013-08-02 14:26:58 +0000216#define MSAN_MALLOC_HOOK(ptr, size) \
Alexey Samsonov91bb8e02014-07-07 17:39:31 +0000217 if (&__sanitizer_malloc_hook) __sanitizer_malloc_hook(ptr, size)
Evgeniy Stepanov44b77c22013-08-02 14:26:58 +0000218#define MSAN_FREE_HOOK(ptr) \
Alexey Samsonov91bb8e02014-07-07 17:39:31 +0000219 if (&__sanitizer_free_hook) __sanitizer_free_hook(ptr)
Evgeniy Stepanov44b77c22013-08-02 14:26:58 +0000220
Evgeniy Stepanovc5033782012-12-11 12:27:27 +0000221#endif // MSAN_H