]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/compiler-rt/lib/asan/asan_descriptions.h
Update ena-com HAL to v1.1.4.3 and update driver accordingly
[FreeBSD/FreeBSD.git] / contrib / compiler-rt / lib / asan / asan_descriptions.h
1 //===-- asan_descriptions.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 AddressSanitizer, an address sanity checker.
11 //
12 // ASan-private header for asan_descriptions.cc.
13 // TODO(filcab): Most struct definitions should move to the interface headers.
14 //===----------------------------------------------------------------------===//
15 #ifndef ASAN_DESCRIPTIONS_H
16 #define ASAN_DESCRIPTIONS_H
17
18 #include "asan_allocator.h"
19 #include "asan_thread.h"
20 #include "sanitizer_common/sanitizer_common.h"
21 #include "sanitizer_common/sanitizer_report_decorator.h"
22
23 namespace __asan {
24
25 void DescribeThread(AsanThreadContext *context);
26 static inline void DescribeThread(AsanThread *t) {
27   if (t) DescribeThread(t->context());
28 }
29 const char *ThreadNameWithParenthesis(AsanThreadContext *t, char buff[],
30                                       uptr buff_len);
31 const char *ThreadNameWithParenthesis(u32 tid, char buff[], uptr buff_len);
32
33 class Decorator : public __sanitizer::SanitizerCommonDecorator {
34  public:
35   Decorator() : SanitizerCommonDecorator() {}
36   const char *Access() { return Blue(); }
37   const char *EndAccess() { return Default(); }
38   const char *Location() { return Green(); }
39   const char *EndLocation() { return Default(); }
40   const char *Allocation() { return Magenta(); }
41   const char *EndAllocation() { return Default(); }
42
43   const char *ShadowByte(u8 byte) {
44     switch (byte) {
45       case kAsanHeapLeftRedzoneMagic:
46       case kAsanArrayCookieMagic:
47         return Red();
48       case kAsanHeapFreeMagic:
49         return Magenta();
50       case kAsanStackLeftRedzoneMagic:
51       case kAsanStackMidRedzoneMagic:
52       case kAsanStackRightRedzoneMagic:
53         return Red();
54       case kAsanStackAfterReturnMagic:
55         return Magenta();
56       case kAsanInitializationOrderMagic:
57         return Cyan();
58       case kAsanUserPoisonedMemoryMagic:
59       case kAsanContiguousContainerOOBMagic:
60       case kAsanAllocaLeftMagic:
61       case kAsanAllocaRightMagic:
62         return Blue();
63       case kAsanStackUseAfterScopeMagic:
64         return Magenta();
65       case kAsanGlobalRedzoneMagic:
66         return Red();
67       case kAsanInternalHeapMagic:
68         return Yellow();
69       case kAsanIntraObjectRedzone:
70         return Yellow();
71       default:
72         return Default();
73     }
74   }
75   const char *EndShadowByte() { return Default(); }
76   const char *MemoryByte() { return Magenta(); }
77   const char *EndMemoryByte() { return Default(); }
78 };
79
80 enum ShadowKind : u8 {
81   kShadowKindLow,
82   kShadowKindGap,
83   kShadowKindHigh,
84 };
85 static const char *const ShadowNames[] = {"low shadow", "shadow gap",
86                                           "high shadow"};
87
88 struct ShadowAddressDescription {
89   uptr addr;
90   ShadowKind kind;
91   u8 shadow_byte;
92
93   void Print() const;
94 };
95
96 bool GetShadowAddressInformation(uptr addr, ShadowAddressDescription *descr);
97 bool DescribeAddressIfShadow(uptr addr);
98
99 enum AccessType {
100   kAccessTypeLeft,
101   kAccessTypeRight,
102   kAccessTypeInside,
103   kAccessTypeUnknown,  // This means we have an AddressSanitizer bug!
104 };
105
106 struct ChunkAccess {
107   uptr bad_addr;
108   sptr offset;
109   uptr chunk_begin;
110   uptr chunk_size;
111   u32 access_type : 2;
112   u32 alloc_type : 2;
113 };
114
115 struct HeapAddressDescription {
116   uptr addr;
117   uptr alloc_tid;
118   uptr free_tid;
119   u32 alloc_stack_id;
120   u32 free_stack_id;
121   ChunkAccess chunk_access;
122
123   void Print() const;
124 };
125
126 bool GetHeapAddressInformation(uptr addr, uptr access_size,
127                                HeapAddressDescription *descr);
128 bool DescribeAddressIfHeap(uptr addr, uptr access_size = 1);
129
130 struct StackAddressDescription {
131   uptr addr;
132   uptr tid;
133   uptr offset;
134   uptr frame_pc;
135   uptr access_size;
136   const char *frame_descr;
137
138   void Print() const;
139 };
140
141 bool GetStackAddressInformation(uptr addr, uptr access_size,
142                                 StackAddressDescription *descr);
143
144 struct GlobalAddressDescription {
145   uptr addr;
146   // Assume address is close to at most four globals.
147   static const int kMaxGlobals = 4;
148   __asan_global globals[kMaxGlobals];
149   u32 reg_sites[kMaxGlobals];
150   uptr access_size;
151   u8 size;
152
153   void Print(const char *bug_type = "") const;
154 };
155
156 bool GetGlobalAddressInformation(uptr addr, uptr access_size,
157                                  GlobalAddressDescription *descr);
158 bool DescribeAddressIfGlobal(uptr addr, uptr access_size, const char *bug_type);
159
160 // General function to describe an address. Will try to describe the address as
161 // a shadow, global (variable), stack, or heap address.
162 // bug_type is optional and is used for checking if we're reporting an
163 // initialization-order-fiasco
164 // The proper access_size should be passed for stack, global, and heap
165 // addresses. Defaults to 1.
166 // Each of the *AddressDescription functions has its own Print() member, which
167 // may take access_size and bug_type parameters if needed.
168 void PrintAddressDescription(uptr addr, uptr access_size = 1,
169                              const char *bug_type = "");
170
171 enum AddressKind {
172   kAddressKindWild,
173   kAddressKindShadow,
174   kAddressKindHeap,
175   kAddressKindStack,
176   kAddressKindGlobal,
177 };
178
179 class AddressDescription {
180   struct AddressDescriptionData {
181     AddressKind kind;
182     union {
183       ShadowAddressDescription shadow;
184       HeapAddressDescription heap;
185       StackAddressDescription stack;
186       GlobalAddressDescription global;
187       uptr addr;
188     };
189   };
190
191   AddressDescriptionData data;
192
193  public:
194   AddressDescription() = default;
195   // shouldLockThreadRegistry allows us to skip locking if we're sure we already
196   // have done it.
197   AddressDescription(uptr addr, bool shouldLockThreadRegistry = true)
198       : AddressDescription(addr, 1, shouldLockThreadRegistry) {}
199   AddressDescription(uptr addr, uptr access_size,
200                      bool shouldLockThreadRegistry = true);
201
202   uptr Address() const {
203     switch (data.kind) {
204       case kAddressKindWild:
205         return data.addr;
206       case kAddressKindShadow:
207         return data.shadow.addr;
208       case kAddressKindHeap:
209         return data.heap.addr;
210       case kAddressKindStack:
211         return data.stack.addr;
212       case kAddressKindGlobal:
213         return data.global.addr;
214     }
215     UNREACHABLE("AddressInformation kind is invalid");
216   }
217   void Print(const char *bug_descr = nullptr) const {
218     switch (data.kind) {
219       case kAddressKindWild:
220         Printf("Address %p is a wild pointer.\n", data.addr);
221         return;
222       case kAddressKindShadow:
223         return data.shadow.Print();
224       case kAddressKindHeap:
225         return data.heap.Print();
226       case kAddressKindStack:
227         return data.stack.Print();
228       case kAddressKindGlobal:
229         // initialization-order-fiasco has a special Print()
230         return data.global.Print(bug_descr);
231     }
232     UNREACHABLE("AddressInformation kind is invalid");
233   }
234
235   void StoreTo(AddressDescriptionData *dst) const { *dst = data; }
236
237   const ShadowAddressDescription *AsShadow() const {
238     return data.kind == kAddressKindShadow ? &data.shadow : nullptr;
239   }
240   const HeapAddressDescription *AsHeap() const {
241     return data.kind == kAddressKindHeap ? &data.heap : nullptr;
242   }
243   const StackAddressDescription *AsStack() const {
244     return data.kind == kAddressKindStack ? &data.stack : nullptr;
245   }
246   const GlobalAddressDescription *AsGlobal() const {
247     return data.kind == kAddressKindGlobal ? &data.global : nullptr;
248   }
249 };
250
251 }  // namespace __asan
252
253 #endif  // ASAN_DESCRIPTIONS_H