[RISCV] Reduce redundancy in vnsrl tests
[llvm-project.git] / compiler-rt / lib / asan / asan_errors.h
blobb3af655e66639a90079f59397a4d542eff50d0e6
1 //===-- asan_errors.h -------------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file is a part of AddressSanitizer, an address sanity checker.
11 // ASan-private header for error structures.
12 //===----------------------------------------------------------------------===//
13 #ifndef ASAN_ERRORS_H
14 #define ASAN_ERRORS_H
16 #include "asan_descriptions.h"
17 #include "asan_scariness_score.h"
18 #include "sanitizer_common/sanitizer_common.h"
20 namespace __asan {
22 // (*) VS2013 does not implement unrestricted unions, so we need a trivial
23 // default constructor explicitly defined for each particular error.
25 // None of the error classes own the stack traces mentioned in them.
27 struct ErrorBase {
28 ScarinessScoreBase scariness;
29 u32 tid;
31 ErrorBase() = default; // (*)
32 explicit ErrorBase(u32 tid_) : tid(tid_) {}
33 ErrorBase(u32 tid_, int initial_score, const char *reason) : tid(tid_) {
34 scariness.Clear();
35 scariness.Scare(initial_score, reason);
39 struct ErrorDeadlySignal : ErrorBase {
40 SignalContext signal;
42 ErrorDeadlySignal() = default; // (*)
43 ErrorDeadlySignal(u32 tid, const SignalContext &sig)
44 : ErrorBase(tid),
45 signal(sig) {
46 scariness.Clear();
47 if (signal.IsStackOverflow()) {
48 scariness.Scare(10, "stack-overflow");
49 } else if (!signal.is_memory_access) {
50 scariness.Scare(10, "signal");
51 } else if (signal.is_true_faulting_addr &&
52 signal.addr < GetPageSizeCached()) {
53 scariness.Scare(10, "null-deref");
54 } else if (signal.addr == signal.pc) {
55 scariness.Scare(60, "wild-jump");
56 } else if (signal.write_flag == SignalContext::Write) {
57 scariness.Scare(30, "wild-addr-write");
58 } else if (signal.write_flag == SignalContext::Read) {
59 scariness.Scare(20, "wild-addr-read");
60 } else {
61 scariness.Scare(25, "wild-addr");
64 void Print();
67 struct ErrorDoubleFree : ErrorBase {
68 const BufferedStackTrace *second_free_stack;
69 HeapAddressDescription addr_description;
71 ErrorDoubleFree() = default; // (*)
72 ErrorDoubleFree(u32 tid, BufferedStackTrace *stack, uptr addr)
73 : ErrorBase(tid, 42, "double-free"),
74 second_free_stack(stack) {
75 CHECK_GT(second_free_stack->size, 0);
76 GetHeapAddressInformation(addr, 1, &addr_description);
78 void Print();
81 struct ErrorNewDeleteTypeMismatch : ErrorBase {
82 const BufferedStackTrace *free_stack;
83 HeapAddressDescription addr_description;
84 uptr delete_size;
85 uptr delete_alignment;
87 ErrorNewDeleteTypeMismatch() = default; // (*)
88 ErrorNewDeleteTypeMismatch(u32 tid, BufferedStackTrace *stack, uptr addr,
89 uptr delete_size_, uptr delete_alignment_)
90 : ErrorBase(tid, 10, "new-delete-type-mismatch"),
91 free_stack(stack),
92 delete_size(delete_size_),
93 delete_alignment(delete_alignment_) {
94 GetHeapAddressInformation(addr, 1, &addr_description);
96 void Print();
99 struct ErrorFreeNotMalloced : ErrorBase {
100 const BufferedStackTrace *free_stack;
101 AddressDescription addr_description;
103 ErrorFreeNotMalloced() = default; // (*)
104 ErrorFreeNotMalloced(u32 tid, BufferedStackTrace *stack, uptr addr)
105 : ErrorBase(tid, 40, "bad-free"),
106 free_stack(stack),
107 addr_description(addr, /*shouldLockThreadRegistry=*/false) {}
108 void Print();
111 struct ErrorAllocTypeMismatch : ErrorBase {
112 const BufferedStackTrace *dealloc_stack;
113 AllocType alloc_type, dealloc_type;
114 AddressDescription addr_description;
116 ErrorAllocTypeMismatch() = default; // (*)
117 ErrorAllocTypeMismatch(u32 tid, BufferedStackTrace *stack, uptr addr,
118 AllocType alloc_type_, AllocType dealloc_type_)
119 : ErrorBase(tid, 10, "alloc-dealloc-mismatch"),
120 dealloc_stack(stack),
121 alloc_type(alloc_type_),
122 dealloc_type(dealloc_type_),
123 addr_description(addr, 1, false) {}
124 void Print();
127 struct ErrorMallocUsableSizeNotOwned : ErrorBase {
128 const BufferedStackTrace *stack;
129 AddressDescription addr_description;
131 ErrorMallocUsableSizeNotOwned() = default; // (*)
132 ErrorMallocUsableSizeNotOwned(u32 tid, BufferedStackTrace *stack_, uptr addr)
133 : ErrorBase(tid, 10, "bad-malloc_usable_size"),
134 stack(stack_),
135 addr_description(addr, /*shouldLockThreadRegistry=*/false) {}
136 void Print();
139 struct ErrorSanitizerGetAllocatedSizeNotOwned : ErrorBase {
140 const BufferedStackTrace *stack;
141 AddressDescription addr_description;
143 ErrorSanitizerGetAllocatedSizeNotOwned() = default; // (*)
144 ErrorSanitizerGetAllocatedSizeNotOwned(u32 tid, BufferedStackTrace *stack_,
145 uptr addr)
146 : ErrorBase(tid, 10, "bad-__sanitizer_get_allocated_size"),
147 stack(stack_),
148 addr_description(addr, /*shouldLockThreadRegistry=*/false) {}
149 void Print();
152 struct ErrorCallocOverflow : ErrorBase {
153 const BufferedStackTrace *stack;
154 uptr count;
155 uptr size;
157 ErrorCallocOverflow() = default; // (*)
158 ErrorCallocOverflow(u32 tid, BufferedStackTrace *stack_, uptr count_,
159 uptr size_)
160 : ErrorBase(tid, 10, "calloc-overflow"),
161 stack(stack_),
162 count(count_),
163 size(size_) {}
164 void Print();
167 struct ErrorReallocArrayOverflow : ErrorBase {
168 const BufferedStackTrace *stack;
169 uptr count;
170 uptr size;
172 ErrorReallocArrayOverflow() = default; // (*)
173 ErrorReallocArrayOverflow(u32 tid, BufferedStackTrace *stack_, uptr count_,
174 uptr size_)
175 : ErrorBase(tid, 10, "reallocarray-overflow"),
176 stack(stack_),
177 count(count_),
178 size(size_) {}
179 void Print();
182 struct ErrorPvallocOverflow : ErrorBase {
183 const BufferedStackTrace *stack;
184 uptr size;
186 ErrorPvallocOverflow() = default; // (*)
187 ErrorPvallocOverflow(u32 tid, BufferedStackTrace *stack_, uptr size_)
188 : ErrorBase(tid, 10, "pvalloc-overflow"),
189 stack(stack_),
190 size(size_) {}
191 void Print();
194 struct ErrorInvalidAllocationAlignment : ErrorBase {
195 const BufferedStackTrace *stack;
196 uptr alignment;
198 ErrorInvalidAllocationAlignment() = default; // (*)
199 ErrorInvalidAllocationAlignment(u32 tid, BufferedStackTrace *stack_,
200 uptr alignment_)
201 : ErrorBase(tid, 10, "invalid-allocation-alignment"),
202 stack(stack_),
203 alignment(alignment_) {}
204 void Print();
207 struct ErrorInvalidAlignedAllocAlignment : ErrorBase {
208 const BufferedStackTrace *stack;
209 uptr size;
210 uptr alignment;
212 ErrorInvalidAlignedAllocAlignment() = default; // (*)
213 ErrorInvalidAlignedAllocAlignment(u32 tid, BufferedStackTrace *stack_,
214 uptr size_, uptr alignment_)
215 : ErrorBase(tid, 10, "invalid-aligned-alloc-alignment"),
216 stack(stack_),
217 size(size_),
218 alignment(alignment_) {}
219 void Print();
222 struct ErrorInvalidPosixMemalignAlignment : ErrorBase {
223 const BufferedStackTrace *stack;
224 uptr alignment;
226 ErrorInvalidPosixMemalignAlignment() = default; // (*)
227 ErrorInvalidPosixMemalignAlignment(u32 tid, BufferedStackTrace *stack_,
228 uptr alignment_)
229 : ErrorBase(tid, 10, "invalid-posix-memalign-alignment"),
230 stack(stack_),
231 alignment(alignment_) {}
232 void Print();
235 struct ErrorAllocationSizeTooBig : ErrorBase {
236 const BufferedStackTrace *stack;
237 uptr user_size;
238 uptr total_size;
239 uptr max_size;
241 ErrorAllocationSizeTooBig() = default; // (*)
242 ErrorAllocationSizeTooBig(u32 tid, BufferedStackTrace *stack_,
243 uptr user_size_, uptr total_size_, uptr max_size_)
244 : ErrorBase(tid, 10, "allocation-size-too-big"),
245 stack(stack_),
246 user_size(user_size_),
247 total_size(total_size_),
248 max_size(max_size_) {}
249 void Print();
252 struct ErrorRssLimitExceeded : ErrorBase {
253 const BufferedStackTrace *stack;
255 ErrorRssLimitExceeded() = default; // (*)
256 ErrorRssLimitExceeded(u32 tid, BufferedStackTrace *stack_)
257 : ErrorBase(tid, 10, "rss-limit-exceeded"),
258 stack(stack_) {}
259 void Print();
262 struct ErrorOutOfMemory : ErrorBase {
263 const BufferedStackTrace *stack;
264 uptr requested_size;
266 ErrorOutOfMemory() = default; // (*)
267 ErrorOutOfMemory(u32 tid, BufferedStackTrace *stack_, uptr requested_size_)
268 : ErrorBase(tid, 10, "out-of-memory"),
269 stack(stack_),
270 requested_size(requested_size_) {}
271 void Print();
274 struct ErrorStringFunctionMemoryRangesOverlap : ErrorBase {
275 const BufferedStackTrace *stack;
276 uptr length1, length2;
277 AddressDescription addr1_description;
278 AddressDescription addr2_description;
279 const char *function;
281 ErrorStringFunctionMemoryRangesOverlap() = default; // (*)
282 ErrorStringFunctionMemoryRangesOverlap(u32 tid, BufferedStackTrace *stack_,
283 uptr addr1, uptr length1_, uptr addr2,
284 uptr length2_, const char *function_)
285 : ErrorBase(tid),
286 stack(stack_),
287 length1(length1_),
288 length2(length2_),
289 addr1_description(addr1, length1, /*shouldLockThreadRegistry=*/false),
290 addr2_description(addr2, length2, /*shouldLockThreadRegistry=*/false),
291 function(function_) {
292 char bug_type[100];
293 internal_snprintf(bug_type, sizeof(bug_type), "%s-param-overlap", function);
294 scariness.Clear();
295 scariness.Scare(10, bug_type);
297 void Print();
300 struct ErrorStringFunctionSizeOverflow : ErrorBase {
301 const BufferedStackTrace *stack;
302 AddressDescription addr_description;
303 uptr size;
305 ErrorStringFunctionSizeOverflow() = default; // (*)
306 ErrorStringFunctionSizeOverflow(u32 tid, BufferedStackTrace *stack_,
307 uptr addr, uptr size_)
308 : ErrorBase(tid, 10, "negative-size-param"),
309 stack(stack_),
310 addr_description(addr, /*shouldLockThreadRegistry=*/false),
311 size(size_) {}
312 void Print();
315 struct ErrorBadParamsToAnnotateContiguousContainer : ErrorBase {
316 const BufferedStackTrace *stack;
317 uptr beg, end, old_mid, new_mid;
319 ErrorBadParamsToAnnotateContiguousContainer() = default; // (*)
320 // PS4: Do we want an AddressDescription for beg?
321 ErrorBadParamsToAnnotateContiguousContainer(u32 tid,
322 BufferedStackTrace *stack_,
323 uptr beg_, uptr end_,
324 uptr old_mid_, uptr new_mid_)
325 : ErrorBase(tid, 10, "bad-__sanitizer_annotate_contiguous_container"),
326 stack(stack_),
327 beg(beg_),
328 end(end_),
329 old_mid(old_mid_),
330 new_mid(new_mid_) {}
331 void Print();
334 struct ErrorBadParamsToAnnotateDoubleEndedContiguousContainer : ErrorBase {
335 const BufferedStackTrace *stack;
336 uptr storage_beg, storage_end, old_container_beg, old_container_end,
337 new_container_beg, new_container_end;
339 ErrorBadParamsToAnnotateDoubleEndedContiguousContainer() = default; // (*)
340 ErrorBadParamsToAnnotateDoubleEndedContiguousContainer(
341 u32 tid, BufferedStackTrace *stack_, uptr storage_beg_, uptr storage_end_,
342 uptr old_container_beg_, uptr old_container_end_, uptr new_container_beg_,
343 uptr new_container_end_)
344 : ErrorBase(tid, 10,
345 "bad-__sanitizer_annotate_double_ended_contiguous_container"),
346 stack(stack_),
347 storage_beg(storage_beg_),
348 storage_end(storage_end_),
349 old_container_beg(old_container_beg_),
350 old_container_end(old_container_end_),
351 new_container_beg(new_container_beg_),
352 new_container_end(new_container_end_) {}
353 void Print();
356 struct ErrorBadParamsToCopyContiguousContainerAnnotations : ErrorBase {
357 const BufferedStackTrace *stack;
358 uptr old_storage_beg, old_storage_end, new_storage_beg, new_storage_end;
360 ErrorBadParamsToCopyContiguousContainerAnnotations() = default; // (*)
361 ErrorBadParamsToCopyContiguousContainerAnnotations(
362 u32 tid, BufferedStackTrace *stack_, uptr old_storage_beg_,
363 uptr old_storage_end_, uptr new_storage_beg_, uptr new_storage_end_)
364 : ErrorBase(tid, 10,
365 "bad-__sanitizer_annotate_double_ended_contiguous_container"),
366 stack(stack_),
367 old_storage_beg(old_storage_beg_),
368 old_storage_end(old_storage_end_),
369 new_storage_beg(new_storage_beg_),
370 new_storage_end(new_storage_end_) {}
371 void Print();
374 struct ErrorODRViolation : ErrorBase {
375 __asan_global global1, global2;
376 u32 stack_id1, stack_id2;
378 ErrorODRViolation() = default; // (*)
379 ErrorODRViolation(u32 tid, const __asan_global *g1, u32 stack_id1_,
380 const __asan_global *g2, u32 stack_id2_)
381 : ErrorBase(tid, 10, "odr-violation"),
382 global1(*g1),
383 global2(*g2),
384 stack_id1(stack_id1_),
385 stack_id2(stack_id2_) {}
386 void Print();
389 struct ErrorInvalidPointerPair : ErrorBase {
390 uptr pc, bp, sp;
391 AddressDescription addr1_description;
392 AddressDescription addr2_description;
394 ErrorInvalidPointerPair() = default; // (*)
395 ErrorInvalidPointerPair(u32 tid, uptr pc_, uptr bp_, uptr sp_, uptr p1,
396 uptr p2)
397 : ErrorBase(tid, 10, "invalid-pointer-pair"),
398 pc(pc_),
399 bp(bp_),
400 sp(sp_),
401 addr1_description(p1, 1, /*shouldLockThreadRegistry=*/false),
402 addr2_description(p2, 1, /*shouldLockThreadRegistry=*/false) {}
403 void Print();
406 struct ErrorGeneric : ErrorBase {
407 AddressDescription addr_description;
408 uptr pc, bp, sp;
409 uptr access_size;
410 const char *bug_descr;
411 bool is_write;
412 u8 shadow_val;
414 ErrorGeneric() = default; // (*)
415 ErrorGeneric(u32 tid, uptr pc_, uptr bp_, uptr sp_, uptr addr, bool is_write_,
416 uptr access_size_);
417 void Print();
420 // clang-format off
421 #define ASAN_FOR_EACH_ERROR_KIND(macro) \
422 macro(DeadlySignal) \
423 macro(DoubleFree) \
424 macro(NewDeleteTypeMismatch) \
425 macro(FreeNotMalloced) \
426 macro(AllocTypeMismatch) \
427 macro(MallocUsableSizeNotOwned) \
428 macro(SanitizerGetAllocatedSizeNotOwned) \
429 macro(CallocOverflow) \
430 macro(ReallocArrayOverflow) \
431 macro(PvallocOverflow) \
432 macro(InvalidAllocationAlignment) \
433 macro(InvalidAlignedAllocAlignment) \
434 macro(InvalidPosixMemalignAlignment) \
435 macro(AllocationSizeTooBig) \
436 macro(RssLimitExceeded) \
437 macro(OutOfMemory) \
438 macro(StringFunctionMemoryRangesOverlap) \
439 macro(StringFunctionSizeOverflow) \
440 macro(BadParamsToAnnotateContiguousContainer) \
441 macro(BadParamsToAnnotateDoubleEndedContiguousContainer) \
442 macro(BadParamsToCopyContiguousContainerAnnotations) \
443 macro(ODRViolation) \
444 macro(InvalidPointerPair) \
445 macro(Generic)
446 // clang-format on
448 #define ASAN_DEFINE_ERROR_KIND(name) kErrorKind##name,
449 #define ASAN_ERROR_DESCRIPTION_MEMBER(name) Error##name name;
450 #define ASAN_ERROR_DESCRIPTION_CONSTRUCTOR(name) \
451 ErrorDescription(Error##name const &e) : kind(kErrorKind##name) { \
452 internal_memcpy(&name, &e, sizeof(name)); \
454 #define ASAN_ERROR_DESCRIPTION_PRINT(name) \
455 case kErrorKind##name: \
456 return name.Print();
458 enum ErrorKind {
459 kErrorKindInvalid = 0,
460 ASAN_FOR_EACH_ERROR_KIND(ASAN_DEFINE_ERROR_KIND)
463 struct ErrorDescription {
464 ErrorKind kind;
465 // We're using a tagged union because it allows us to have a trivially
466 // copiable type and use the same structures as the public interface.
468 // We can add a wrapper around it to make it "more c++-like", but that would
469 // add a lot of code and the benefit wouldn't be that big.
470 union {
471 ErrorBase Base;
472 ASAN_FOR_EACH_ERROR_KIND(ASAN_ERROR_DESCRIPTION_MEMBER)
475 ErrorDescription() { internal_memset(this, 0, sizeof(*this)); }
476 explicit ErrorDescription(LinkerInitialized) {}
477 ASAN_FOR_EACH_ERROR_KIND(ASAN_ERROR_DESCRIPTION_CONSTRUCTOR)
479 bool IsValid() { return kind != kErrorKindInvalid; }
480 void Print() {
481 switch (kind) {
482 ASAN_FOR_EACH_ERROR_KIND(ASAN_ERROR_DESCRIPTION_PRINT)
483 case kErrorKindInvalid:
484 CHECK(0);
486 CHECK(0);
490 #undef ASAN_FOR_EACH_ERROR_KIND
491 #undef ASAN_DEFINE_ERROR_KIND
492 #undef ASAN_ERROR_DESCRIPTION_MEMBER
493 #undef ASAN_ERROR_DESCRIPTION_CONSTRUCTOR
494 #undef ASAN_ERROR_DESCRIPTION_PRINT
496 } // namespace __asan
498 #endif // ASAN_ERRORS_H