• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-- msan.h --------------------------------------------------*- C++ -*-===//
2 //
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 
18 #include "sanitizer_common/sanitizer_flags.h"
19 #include "sanitizer_common/sanitizer_internal_defs.h"
20 #include "sanitizer_common/sanitizer_stacktrace.h"
21 #include "msan_interface_internal.h"
22 #include "msan_flags.h"
23 
24 #ifndef MSAN_REPLACE_OPERATORS_NEW_AND_DELETE
25 # define MSAN_REPLACE_OPERATORS_NEW_AND_DELETE 1
26 #endif
27 
28 #define MEM_TO_SHADOW(mem)       (((uptr)mem) & ~0x400000000000ULL)
29 #define SHADOW_TO_ORIGIN(shadow) (((uptr)shadow) + 0x200000000000ULL)
30 #define MEM_TO_ORIGIN(mem)       (SHADOW_TO_ORIGIN(MEM_TO_SHADOW(mem)))
31 #define MEM_IS_APP(mem)          ((uptr)mem >= 0x600000000000ULL)
32 #define MEM_IS_SHADOW(mem) \
33   ((uptr)mem >= 0x200000000000ULL && (uptr)mem <= 0x400000000000ULL)
34 
35 const int kMsanParamTlsSizeInWords = 100;
36 const int kMsanRetvalTlsSizeInWords = 100;
37 
38 namespace __msan {
39 extern int msan_inited;
40 extern bool msan_init_is_running;
41 extern int msan_report_count;
42 
43 bool ProtectRange(uptr beg, uptr end);
44 bool InitShadow(bool prot1, bool prot2, bool map_shadow, bool init_origins);
45 char *GetProcSelfMaps();
46 void InitializeInterceptors();
47 
48 void MsanAllocatorThreadFinish();
49 void *MsanReallocate(StackTrace *stack, void *oldp, uptr size,
50                      uptr alignment, bool zeroise);
51 void MsanDeallocate(StackTrace *stack, void *ptr);
52 void InstallTrapHandler();
53 void InstallAtExitHandler();
54 void ReplaceOperatorsNewAndDelete();
55 
56 const char *GetStackOriginDescr(u32 id, uptr *pc);
57 
58 void EnterSymbolizer();
59 void ExitSymbolizer();
60 bool IsInSymbolizer();
61 
62 struct SymbolizerScope {
SymbolizerScopeSymbolizerScope63   SymbolizerScope() { EnterSymbolizer(); }
~SymbolizerScopeSymbolizerScope64   ~SymbolizerScope() { ExitSymbolizer(); }
65 };
66 
67 void EnterLoader();
68 void ExitLoader();
69 
70 void MsanDie();
71 void PrintWarning(uptr pc, uptr bp);
72 void PrintWarningWithOrigin(uptr pc, uptr bp, u32 origin);
73 
74 void GetStackTrace(StackTrace *stack, uptr max_s, uptr pc, uptr bp,
75                    bool request_fast_unwind);
76 
77 void ReportUMR(StackTrace *stack, u32 origin);
78 void ReportExpectedUMRNotFound(StackTrace *stack);
79 void ReportStats();
80 void ReportAtExitStatistics();
81 void DescribeMemoryRange(const void *x, uptr size);
82 void ReportUMRInsideAddressRange(const char *what, const void *start, uptr size,
83                                  uptr offset);
84 
85 // Unpoison first n function arguments.
86 void UnpoisonParam(uptr n);
87 void UnpoisonThreadLocalState();
88 
89 u32 GetOriginIfPoisoned(uptr a, uptr size);
90 void SetOriginIfPoisoned(uptr addr, uptr src_shadow, uptr size, u32 src_origin);
91 void CopyOrigin(void *dst, const void *src, uptr size, StackTrace *stack);
92 void MovePoison(void *dst, const void *src, uptr size, StackTrace *stack);
93 void CopyPoison(void *dst, const void *src, uptr size, StackTrace *stack);
94 
95 // Returns a "chained" origin id, pointing to the given stack trace followed by
96 // the previous origin id.
97 u32 ChainOrigin(u32 id, StackTrace *stack);
98 
99 #define GET_MALLOC_STACK_TRACE                                     \
100   StackTrace stack;                                                \
101   stack.size = 0;                                                  \
102   if (__msan_get_track_origins() && msan_inited)                   \
103     GetStackTrace(&stack, common_flags()->malloc_context_size,     \
104         StackTrace::GetCurrentPc(), GET_CURRENT_FRAME(),           \
105         common_flags()->fast_unwind_on_malloc)
106 
107 #define GET_STORE_STACK_TRACE_PC_BP(pc, bp)                  \
108   StackTrace stack;                                          \
109   stack.size = 0;                                            \
110   if (__msan_get_track_origins() > 1 && msan_inited)         \
111   GetStackTrace(&stack, flags()->store_context_size, pc, bp, \
112                 common_flags()->fast_unwind_on_malloc)
113 
114 #define GET_FATAL_STACK_TRACE_PC_BP(pc, bp)       \
115   StackTrace stack;                               \
116   stack.size = 0;                                 \
117   if (msan_inited)                                \
118     GetStackTrace(&stack, kStackTraceMax, pc, bp, \
119                   common_flags()->fast_unwind_on_fatal)
120 
121 #define GET_STORE_STACK_TRACE \
122   GET_STORE_STACK_TRACE_PC_BP(StackTrace::GetCurrentPc(), GET_CURRENT_FRAME())
123 
124 class ScopedThreadLocalStateBackup {
125  public:
ScopedThreadLocalStateBackup()126   ScopedThreadLocalStateBackup() { Backup(); }
~ScopedThreadLocalStateBackup()127   ~ScopedThreadLocalStateBackup() { Restore(); }
128   void Backup();
129   void Restore();
130  private:
131   u64 va_arg_overflow_size_tls;
132 };
133 
134 extern void (*death_callback)(void);
135 
136 void MsanTSDInit(void (*destructor)(void *tsd));
137 void *MsanTSDGet();
138 void MsanTSDSet(void *tsd);
139 void MsanTSDDtor(void *tsd);
140 
141 }  // namespace __msan
142 
143 #define MSAN_MALLOC_HOOK(ptr, size) \
144   if (&__msan_malloc_hook) __msan_malloc_hook(ptr, size); \
145   if (&__sanitizer_malloc_hook) __sanitizer_malloc_hook(ptr, size)
146 #define MSAN_FREE_HOOK(ptr) \
147   if (&__msan_free_hook) __msan_free_hook(ptr); \
148   if (&__sanitizer_free_hook) __sanitizer_free_hook(ptr)
149 
150 #endif  // MSAN_H
151