[AArch64] Avoid GET_MODE_NUNITS in v8.4 support
[official-gcc.git] / libsanitizer / asan / asan_errors.h
blobea8fd01e28755d93ab170a33b827e21fc7f38053
1 //===-- asan_errors.h -------------------------------------------*- C++ -*-===//
2 //
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
5 //
6 //===----------------------------------------------------------------------===//
7 //
8 // This file is a part of AddressSanitizer, an address sanity checker.
9 //
10 // ASan-private header for error structures.
11 //===----------------------------------------------------------------------===//
12 #ifndef ASAN_ERRORS_H
13 #define ASAN_ERRORS_H
15 #include "asan_descriptions.h"
16 #include "asan_scariness_score.h"
17 #include "sanitizer_common/sanitizer_common.h"
19 namespace __asan {
21 struct ErrorBase {
22 ErrorBase() = default;
23 explicit ErrorBase(u32 tid_) : tid(tid_) {}
24 ScarinessScoreBase scariness;
25 u32 tid;
28 struct ErrorDeadlySignal : ErrorBase {
29 SignalContext signal;
30 // VS2013 doesn't implement unrestricted unions, so we need a trivial default
31 // constructor
32 ErrorDeadlySignal() = default;
33 ErrorDeadlySignal(u32 tid, const SignalContext &sig)
34 : ErrorBase(tid), signal(sig) {
35 scariness.Clear();
36 if (signal.IsStackOverflow()) {
37 scariness.Scare(10, "stack-overflow");
38 } else if (!signal.is_memory_access) {
39 scariness.Scare(10, "signal");
40 } else if (signal.addr < GetPageSizeCached()) {
41 scariness.Scare(10, "null-deref");
42 } else if (signal.addr == signal.pc) {
43 scariness.Scare(60, "wild-jump");
44 } else if (signal.write_flag == SignalContext::WRITE) {
45 scariness.Scare(30, "wild-addr-write");
46 } else if (signal.write_flag == SignalContext::READ) {
47 scariness.Scare(20, "wild-addr-read");
48 } else {
49 scariness.Scare(25, "wild-addr");
52 void Print();
55 struct ErrorDoubleFree : ErrorBase {
56 // ErrorDoubleFree doesn't own the stack trace.
57 const BufferedStackTrace *second_free_stack;
58 HeapAddressDescription addr_description;
59 // VS2013 doesn't implement unrestricted unions, so we need a trivial default
60 // constructor
61 ErrorDoubleFree() = default;
62 ErrorDoubleFree(u32 tid, BufferedStackTrace *stack, uptr addr)
63 : ErrorBase(tid), second_free_stack(stack) {
64 CHECK_GT(second_free_stack->size, 0);
65 GetHeapAddressInformation(addr, 1, &addr_description);
66 scariness.Clear();
67 scariness.Scare(42, "double-free");
69 void Print();
72 struct ErrorNewDeleteSizeMismatch : ErrorBase {
73 // ErrorNewDeleteSizeMismatch doesn't own the stack trace.
74 const BufferedStackTrace *free_stack;
75 HeapAddressDescription addr_description;
76 uptr delete_size;
77 // VS2013 doesn't implement unrestricted unions, so we need a trivial default
78 // constructor
79 ErrorNewDeleteSizeMismatch() = default;
80 ErrorNewDeleteSizeMismatch(u32 tid, BufferedStackTrace *stack, uptr addr,
81 uptr delete_size_)
82 : ErrorBase(tid), free_stack(stack), delete_size(delete_size_) {
83 GetHeapAddressInformation(addr, 1, &addr_description);
84 scariness.Clear();
85 scariness.Scare(10, "new-delete-type-mismatch");
87 void Print();
90 struct ErrorFreeNotMalloced : ErrorBase {
91 // ErrorFreeNotMalloced doesn't own the stack trace.
92 const BufferedStackTrace *free_stack;
93 AddressDescription addr_description;
94 // VS2013 doesn't implement unrestricted unions, so we need a trivial default
95 // constructor
96 ErrorFreeNotMalloced() = default;
97 ErrorFreeNotMalloced(u32 tid, BufferedStackTrace *stack, uptr addr)
98 : ErrorBase(tid),
99 free_stack(stack),
100 addr_description(addr, /*shouldLockThreadRegistry=*/false) {
101 scariness.Clear();
102 scariness.Scare(40, "bad-free");
104 void Print();
107 struct ErrorAllocTypeMismatch : ErrorBase {
108 // ErrorAllocTypeMismatch doesn't own the stack trace.
109 const BufferedStackTrace *dealloc_stack;
110 HeapAddressDescription addr_description;
111 AllocType alloc_type, dealloc_type;
112 // VS2013 doesn't implement unrestricted unions, so we need a trivial default
113 // constructor
114 ErrorAllocTypeMismatch() = default;
115 ErrorAllocTypeMismatch(u32 tid, BufferedStackTrace *stack, uptr addr,
116 AllocType alloc_type_, AllocType dealloc_type_)
117 : ErrorBase(tid),
118 dealloc_stack(stack),
119 alloc_type(alloc_type_),
120 dealloc_type(dealloc_type_) {
121 GetHeapAddressInformation(addr, 1, &addr_description);
122 scariness.Clear();
123 scariness.Scare(10, "alloc-dealloc-mismatch");
125 void Print();
128 struct ErrorMallocUsableSizeNotOwned : ErrorBase {
129 // ErrorMallocUsableSizeNotOwned doesn't own the stack trace.
130 const BufferedStackTrace *stack;
131 AddressDescription addr_description;
132 // VS2013 doesn't implement unrestricted unions, so we need a trivial default
133 // constructor
134 ErrorMallocUsableSizeNotOwned() = default;
135 ErrorMallocUsableSizeNotOwned(u32 tid, BufferedStackTrace *stack_, uptr addr)
136 : ErrorBase(tid),
137 stack(stack_),
138 addr_description(addr, /*shouldLockThreadRegistry=*/false) {
139 scariness.Clear();
140 scariness.Scare(10, "bad-malloc_usable_size");
142 void Print();
145 struct ErrorSanitizerGetAllocatedSizeNotOwned : ErrorBase {
146 // ErrorSanitizerGetAllocatedSizeNotOwned doesn't own the stack trace.
147 const BufferedStackTrace *stack;
148 AddressDescription addr_description;
149 // VS2013 doesn't implement unrestricted unions, so we need a trivial default
150 // constructor
151 ErrorSanitizerGetAllocatedSizeNotOwned() = default;
152 ErrorSanitizerGetAllocatedSizeNotOwned(u32 tid, BufferedStackTrace *stack_,
153 uptr addr)
154 : ErrorBase(tid),
155 stack(stack_),
156 addr_description(addr, /*shouldLockThreadRegistry=*/false) {
157 scariness.Clear();
158 scariness.Scare(10, "bad-__sanitizer_get_allocated_size");
160 void Print();
163 struct ErrorStringFunctionMemoryRangesOverlap : ErrorBase {
164 // ErrorStringFunctionMemoryRangesOverlap doesn't own the stack trace.
165 const BufferedStackTrace *stack;
166 uptr length1, length2;
167 AddressDescription addr1_description;
168 AddressDescription addr2_description;
169 const char *function;
170 // VS2013 doesn't implement unrestricted unions, so we need a trivial default
171 // constructor
172 ErrorStringFunctionMemoryRangesOverlap() = default;
173 ErrorStringFunctionMemoryRangesOverlap(u32 tid, BufferedStackTrace *stack_,
174 uptr addr1, uptr length1_, uptr addr2,
175 uptr length2_, const char *function_)
176 : ErrorBase(tid),
177 stack(stack_),
178 length1(length1_),
179 length2(length2_),
180 addr1_description(addr1, length1, /*shouldLockThreadRegistry=*/false),
181 addr2_description(addr2, length2, /*shouldLockThreadRegistry=*/false),
182 function(function_) {
183 char bug_type[100];
184 internal_snprintf(bug_type, sizeof(bug_type), "%s-param-overlap", function);
185 scariness.Clear();
186 scariness.Scare(10, bug_type);
188 void Print();
191 struct ErrorStringFunctionSizeOverflow : ErrorBase {
192 // ErrorStringFunctionSizeOverflow doesn't own the stack trace.
193 const BufferedStackTrace *stack;
194 AddressDescription addr_description;
195 uptr size;
196 // VS2013 doesn't implement unrestricted unions, so we need a trivial default
197 // constructor
198 ErrorStringFunctionSizeOverflow() = default;
199 ErrorStringFunctionSizeOverflow(u32 tid, BufferedStackTrace *stack_,
200 uptr addr, uptr size_)
201 : ErrorBase(tid),
202 stack(stack_),
203 addr_description(addr, /*shouldLockThreadRegistry=*/false),
204 size(size_) {
205 scariness.Clear();
206 scariness.Scare(10, "negative-size-param");
208 void Print();
211 struct ErrorBadParamsToAnnotateContiguousContainer : ErrorBase {
212 // ErrorBadParamsToAnnotateContiguousContainer doesn't own the stack trace.
213 const BufferedStackTrace *stack;
214 uptr beg, end, old_mid, new_mid;
215 // VS2013 doesn't implement unrestricted unions, so we need a trivial default
216 // constructor
217 ErrorBadParamsToAnnotateContiguousContainer() = default;
218 // PS4: Do we want an AddressDescription for beg?
219 ErrorBadParamsToAnnotateContiguousContainer(u32 tid,
220 BufferedStackTrace *stack_,
221 uptr beg_, uptr end_,
222 uptr old_mid_, uptr new_mid_)
223 : ErrorBase(tid),
224 stack(stack_),
225 beg(beg_),
226 end(end_),
227 old_mid(old_mid_),
228 new_mid(new_mid_) {
229 scariness.Clear();
230 scariness.Scare(10, "bad-__sanitizer_annotate_contiguous_container");
232 void Print();
235 struct ErrorODRViolation : ErrorBase {
236 __asan_global global1, global2;
237 u32 stack_id1, stack_id2;
238 // VS2013 doesn't implement unrestricted unions, so we need a trivial default
239 // constructor
240 ErrorODRViolation() = default;
241 ErrorODRViolation(u32 tid, const __asan_global *g1, u32 stack_id1_,
242 const __asan_global *g2, u32 stack_id2_)
243 : ErrorBase(tid),
244 global1(*g1),
245 global2(*g2),
246 stack_id1(stack_id1_),
247 stack_id2(stack_id2_) {
248 scariness.Clear();
249 scariness.Scare(10, "odr-violation");
251 void Print();
254 struct ErrorInvalidPointerPair : ErrorBase {
255 uptr pc, bp, sp;
256 AddressDescription addr1_description;
257 AddressDescription addr2_description;
258 // VS2013 doesn't implement unrestricted unions, so we need a trivial default
259 // constructor
260 ErrorInvalidPointerPair() = default;
261 ErrorInvalidPointerPair(u32 tid, uptr pc_, uptr bp_, uptr sp_, uptr p1,
262 uptr p2)
263 : ErrorBase(tid),
264 pc(pc_),
265 bp(bp_),
266 sp(sp_),
267 addr1_description(p1, 1, /*shouldLockThreadRegistry=*/false),
268 addr2_description(p2, 1, /*shouldLockThreadRegistry=*/false) {
269 scariness.Clear();
270 scariness.Scare(10, "invalid-pointer-pair");
272 void Print();
275 struct ErrorGeneric : ErrorBase {
276 AddressDescription addr_description;
277 uptr pc, bp, sp;
278 uptr access_size;
279 const char *bug_descr;
280 bool is_write;
281 u8 shadow_val;
282 // VS2013 doesn't implement unrestricted unions, so we need a trivial default
283 // constructor
284 ErrorGeneric() = default;
285 ErrorGeneric(u32 tid, uptr addr, uptr pc_, uptr bp_, uptr sp_, bool is_write_,
286 uptr access_size_);
287 void Print();
290 // clang-format off
291 #define ASAN_FOR_EACH_ERROR_KIND(macro) \
292 macro(DeadlySignal) \
293 macro(DoubleFree) \
294 macro(NewDeleteSizeMismatch) \
295 macro(FreeNotMalloced) \
296 macro(AllocTypeMismatch) \
297 macro(MallocUsableSizeNotOwned) \
298 macro(SanitizerGetAllocatedSizeNotOwned) \
299 macro(StringFunctionMemoryRangesOverlap) \
300 macro(StringFunctionSizeOverflow) \
301 macro(BadParamsToAnnotateContiguousContainer) \
302 macro(ODRViolation) \
303 macro(InvalidPointerPair) \
304 macro(Generic)
305 // clang-format on
307 #define ASAN_DEFINE_ERROR_KIND(name) kErrorKind##name,
308 #define ASAN_ERROR_DESCRIPTION_MEMBER(name) Error##name name;
309 #define ASAN_ERROR_DESCRIPTION_CONSTRUCTOR(name) \
310 ErrorDescription(Error##name const &e) : kind(kErrorKind##name), name(e) {}
311 #define ASAN_ERROR_DESCRIPTION_PRINT(name) \
312 case kErrorKind##name: \
313 return name.Print();
315 enum ErrorKind {
316 kErrorKindInvalid = 0,
317 ASAN_FOR_EACH_ERROR_KIND(ASAN_DEFINE_ERROR_KIND)
320 struct ErrorDescription {
321 ErrorKind kind;
322 // We're using a tagged union because it allows us to have a trivially
323 // copiable type and use the same structures as the public interface.
325 // We can add a wrapper around it to make it "more c++-like", but that would
326 // add a lot of code and the benefit wouldn't be that big.
327 union {
328 ErrorBase Base;
329 ASAN_FOR_EACH_ERROR_KIND(ASAN_ERROR_DESCRIPTION_MEMBER)
332 ErrorDescription() { internal_memset(this, 0, sizeof(*this)); }
333 ASAN_FOR_EACH_ERROR_KIND(ASAN_ERROR_DESCRIPTION_CONSTRUCTOR)
335 bool IsValid() { return kind != kErrorKindInvalid; }
336 void Print() {
337 switch (kind) {
338 ASAN_FOR_EACH_ERROR_KIND(ASAN_ERROR_DESCRIPTION_PRINT)
339 case kErrorKindInvalid:
340 CHECK(0);
342 CHECK(0);
346 #undef ASAN_FOR_EACH_ERROR_KIND
347 #undef ASAN_DEFINE_ERROR_KIND
348 #undef ASAN_ERROR_DESCRIPTION_MEMBER
349 #undef ASAN_ERROR_DESCRIPTION_CONSTRUCTOR
350 #undef ASAN_ERROR_DESCRIPTION_PRINT
352 } // namespace __asan
354 #endif // ASAN_ERRORS_H