]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/compiler-rt/lib/hwasan/hwasan.h
MFV r339750:
[FreeBSD/FreeBSD.git] / contrib / compiler-rt / lib / hwasan / hwasan.h
1 //===-- hwasan.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 HWAddressSanitizer.
11 //
12 // Private Hwasan header.
13 //===----------------------------------------------------------------------===//
14
15 #ifndef HWASAN_H
16 #define HWASAN_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 "hwasan_interface_internal.h"
22 #include "hwasan_flags.h"
23 #include "ubsan/ubsan_platform.h"
24
25 #ifndef HWASAN_REPLACE_OPERATORS_NEW_AND_DELETE
26 # define HWASAN_REPLACE_OPERATORS_NEW_AND_DELETE 1
27 #endif
28
29 #ifndef HWASAN_CONTAINS_UBSAN
30 # define HWASAN_CONTAINS_UBSAN CAN_SANITIZE_UB
31 #endif
32
33 typedef u8 tag_t;
34
35 // Reasonable values are 4 (for 1/16th shadow) and 6 (for 1/64th).
36 const uptr kShadowScale = 4;
37 const uptr kShadowAlignment = 1UL << kShadowScale;
38
39 #define MEM_TO_SHADOW_OFFSET(mem) ((uptr)(mem) >> kShadowScale)
40 #define MEM_TO_SHADOW(mem) ((uptr)(mem) >> kShadowScale)
41 #define SHADOW_TO_MEM(shadow) ((uptr)(shadow) << kShadowScale)
42
43 #define MEM_IS_APP(mem) true
44
45 // TBI (Top Byte Ignore) feature of AArch64: bits [63:56] are ignored in address
46 // translation and can be used to store a tag.
47 const unsigned kAddressTagShift = 56;
48 const uptr kAddressTagMask = 0xFFUL << kAddressTagShift;
49
50 static inline tag_t GetTagFromPointer(uptr p) {
51   return p >> kAddressTagShift;
52 }
53
54 static inline uptr GetAddressFromPointer(uptr p) {
55   return p & ~kAddressTagMask;
56 }
57
58 static inline void * GetAddressFromPointer(const void *p) {
59   return (void *)((uptr)p & ~kAddressTagMask);
60 }
61
62 static inline uptr AddTagToPointer(uptr p, tag_t tag) {
63   return (p & ~kAddressTagMask) | ((uptr)tag << kAddressTagShift);
64 }
65
66 namespace __hwasan {
67
68 extern int hwasan_inited;
69 extern bool hwasan_init_is_running;
70 extern int hwasan_report_count;
71
72 bool ProtectRange(uptr beg, uptr end);
73 bool InitShadow();
74 char *GetProcSelfMaps();
75 void InitializeInterceptors();
76
77 void HwasanAllocatorInit();
78 void HwasanAllocatorThreadFinish();
79 void HwasanDeallocate(StackTrace *stack, void *ptr);
80
81 void *hwasan_malloc(uptr size, StackTrace *stack);
82 void *hwasan_calloc(uptr nmemb, uptr size, StackTrace *stack);
83 void *hwasan_realloc(void *ptr, uptr size, StackTrace *stack);
84 void *hwasan_valloc(uptr size, StackTrace *stack);
85 void *hwasan_pvalloc(uptr size, StackTrace *stack);
86 void *hwasan_aligned_alloc(uptr alignment, uptr size, StackTrace *stack);
87 void *hwasan_memalign(uptr alignment, uptr size, StackTrace *stack);
88 int hwasan_posix_memalign(void **memptr, uptr alignment, uptr size,
89                         StackTrace *stack);
90
91 void InstallTrapHandler();
92 void InstallAtExitHandler();
93
94 const char *GetStackOriginDescr(u32 id, uptr *pc);
95
96 void EnterSymbolizer();
97 void ExitSymbolizer();
98 bool IsInSymbolizer();
99
100 struct SymbolizerScope {
101   SymbolizerScope() { EnterSymbolizer(); }
102   ~SymbolizerScope() { ExitSymbolizer(); }
103 };
104
105 void PrintWarning(uptr pc, uptr bp);
106
107 void GetStackTrace(BufferedStackTrace *stack, uptr max_s, uptr pc, uptr bp,
108                    void *context, bool request_fast_unwind);
109
110 void ReportInvalidAccess(StackTrace *stack, u32 origin);
111 void ReportTagMismatch(StackTrace *stack, uptr addr, uptr access_size,
112                        bool is_store);
113 void ReportStats();
114 void ReportAtExitStatistics();
115 void DescribeMemoryRange(const void *x, uptr size);
116 void ReportInvalidAccessInsideAddressRange(const char *what, const void *start, uptr size,
117                                  uptr offset);
118
119 // Returns a "chained" origin id, pointing to the given stack trace followed by
120 // the previous origin id.
121 u32 ChainOrigin(u32 id, StackTrace *stack);
122
123 const int STACK_TRACE_TAG_POISON = StackTrace::TAG_CUSTOM + 1;
124
125 #define GET_MALLOC_STACK_TRACE                                            \
126   BufferedStackTrace stack;                                               \
127   if (hwasan_inited)                                                       \
128   GetStackTrace(&stack, common_flags()->malloc_context_size,              \
129                 StackTrace::GetCurrentPc(), GET_CURRENT_FRAME(), nullptr, \
130                 common_flags()->fast_unwind_on_malloc)
131
132 #define GET_FATAL_STACK_TRACE_PC_BP(pc, bp)              \
133   BufferedStackTrace stack;                              \
134   if (hwasan_inited)                                       \
135   GetStackTrace(&stack, kStackTraceMax, pc, bp, nullptr, \
136                 common_flags()->fast_unwind_on_fatal)
137
138 class ScopedThreadLocalStateBackup {
139  public:
140   ScopedThreadLocalStateBackup() { Backup(); }
141   ~ScopedThreadLocalStateBackup() { Restore(); }
142   void Backup();
143   void Restore();
144  private:
145   u64 va_arg_overflow_size_tls;
146 };
147
148 void HwasanTSDInit(void (*destructor)(void *tsd));
149 void *HwasanTSDGet();
150 void HwasanTSDSet(void *tsd);
151 void HwasanTSDDtor(void *tsd);
152
153 void HwasanOnDeadlySignal(int signo, void *info, void *context);
154
155 }  // namespace __hwasan
156
157 #define HWASAN_MALLOC_HOOK(ptr, size)       \
158   do {                                    \
159     if (&__sanitizer_malloc_hook) {       \
160       __sanitizer_malloc_hook(ptr, size); \
161     }                                     \
162     RunMallocHooks(ptr, size);            \
163   } while (false)
164 #define HWASAN_FREE_HOOK(ptr)       \
165   do {                            \
166     if (&__sanitizer_free_hook) { \
167       __sanitizer_free_hook(ptr); \
168     }                             \
169     RunFreeHooks(ptr);            \
170   } while (false)
171
172 #endif  // HWASAN_H