Fix build on sparc64-linux-gnu.
[official-gcc.git] / libsanitizer / asan / asan_errors.h
blob5ed15dc9817b4ca26a0e0cf9501bf59d1c721900
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 // (*) VS2013 does not implement unrestricted unions, so we need a trivial
22 // default constructor explicitly defined for each particular error.
24 // None of the error classes own the stack traces mentioned in them.
26 struct ErrorBase {
27 ScarinessScoreBase scariness;
28 u32 tid;
30 ErrorBase() = default; // (*)
31 explicit ErrorBase(u32 tid_) : tid(tid_) {}
32 ErrorBase(u32 tid_, int initial_score, const char *reason) : tid(tid_) {
33 scariness.Clear();
34 scariness.Scare(initial_score, reason);
38 struct ErrorDeadlySignal : ErrorBase {
39 SignalContext signal;
41 ErrorDeadlySignal() = default; // (*)
42 ErrorDeadlySignal(u32 tid, const SignalContext &sig)
43 : ErrorBase(tid),
44 signal(sig) {
45 scariness.Clear();
46 if (signal.IsStackOverflow()) {
47 scariness.Scare(10, "stack-overflow");
48 } else if (!signal.is_memory_access) {
49 scariness.Scare(10, "signal");
50 } else if (signal.addr < GetPageSizeCached()) {
51 scariness.Scare(10, "null-deref");
52 } else if (signal.addr == signal.pc) {
53 scariness.Scare(60, "wild-jump");
54 } else if (signal.write_flag == SignalContext::WRITE) {
55 scariness.Scare(30, "wild-addr-write");
56 } else if (signal.write_flag == SignalContext::READ) {
57 scariness.Scare(20, "wild-addr-read");
58 } else {
59 scariness.Scare(25, "wild-addr");
62 void Print();
65 struct ErrorDoubleFree : ErrorBase {
66 const BufferedStackTrace *second_free_stack;
67 HeapAddressDescription addr_description;
69 ErrorDoubleFree() = default; // (*)
70 ErrorDoubleFree(u32 tid, BufferedStackTrace *stack, uptr addr)
71 : ErrorBase(tid, 42, "double-free"),
72 second_free_stack(stack) {
73 CHECK_GT(second_free_stack->size, 0);
74 GetHeapAddressInformation(addr, 1, &addr_description);
76 void Print();
79 struct ErrorNewDeleteTypeMismatch : ErrorBase {
80 const BufferedStackTrace *free_stack;
81 HeapAddressDescription addr_description;
82 uptr delete_size;
83 uptr delete_alignment;
85 ErrorNewDeleteTypeMismatch() = default; // (*)
86 ErrorNewDeleteTypeMismatch(u32 tid, BufferedStackTrace *stack, uptr addr,
87 uptr delete_size_, uptr delete_alignment_)
88 : ErrorBase(tid, 10, "new-delete-type-mismatch"),
89 free_stack(stack),
90 delete_size(delete_size_),
91 delete_alignment(delete_alignment_) {
92 GetHeapAddressInformation(addr, 1, &addr_description);
94 void Print();
97 struct ErrorFreeNotMalloced : ErrorBase {
98 const BufferedStackTrace *free_stack;
99 AddressDescription addr_description;
101 ErrorFreeNotMalloced() = default; // (*)
102 ErrorFreeNotMalloced(u32 tid, BufferedStackTrace *stack, uptr addr)
103 : ErrorBase(tid, 40, "bad-free"),
104 free_stack(stack),
105 addr_description(addr, /*shouldLockThreadRegistry=*/false) {}
106 void Print();
109 struct ErrorAllocTypeMismatch : ErrorBase {
110 const BufferedStackTrace *dealloc_stack;
111 HeapAddressDescription addr_description;
112 AllocType alloc_type, dealloc_type;
114 ErrorAllocTypeMismatch() = default; // (*)
115 ErrorAllocTypeMismatch(u32 tid, BufferedStackTrace *stack, uptr addr,
116 AllocType alloc_type_, AllocType dealloc_type_)
117 : ErrorBase(tid, 10, "alloc-dealloc-mismatch"),
118 dealloc_stack(stack),
119 alloc_type(alloc_type_),
120 dealloc_type(dealloc_type_) {
121 GetHeapAddressInformation(addr, 1, &addr_description);
123 void Print();
126 struct ErrorMallocUsableSizeNotOwned : ErrorBase {
127 const BufferedStackTrace *stack;
128 AddressDescription addr_description;
130 ErrorMallocUsableSizeNotOwned() = default; // (*)
131 ErrorMallocUsableSizeNotOwned(u32 tid, BufferedStackTrace *stack_, uptr addr)
132 : ErrorBase(tid, 10, "bad-malloc_usable_size"),
133 stack(stack_),
134 addr_description(addr, /*shouldLockThreadRegistry=*/false) {}
135 void Print();
138 struct ErrorSanitizerGetAllocatedSizeNotOwned : ErrorBase {
139 const BufferedStackTrace *stack;
140 AddressDescription addr_description;
142 ErrorSanitizerGetAllocatedSizeNotOwned() = default; // (*)
143 ErrorSanitizerGetAllocatedSizeNotOwned(u32 tid, BufferedStackTrace *stack_,
144 uptr addr)
145 : ErrorBase(tid, 10, "bad-__sanitizer_get_allocated_size"),
146 stack(stack_),
147 addr_description(addr, /*shouldLockThreadRegistry=*/false) {}
148 void Print();
151 struct ErrorCallocOverflow : ErrorBase {
152 const BufferedStackTrace *stack;
153 uptr count;
154 uptr size;
156 ErrorCallocOverflow() = default; // (*)
157 ErrorCallocOverflow(u32 tid, BufferedStackTrace *stack_, uptr count_,
158 uptr size_)
159 : ErrorBase(tid, 10, "calloc-overflow"),
160 stack(stack_),
161 count(count_),
162 size(size_) {}
163 void Print();
166 struct ErrorPvallocOverflow : ErrorBase {
167 const BufferedStackTrace *stack;
168 uptr size;
170 ErrorPvallocOverflow() = default; // (*)
171 ErrorPvallocOverflow(u32 tid, BufferedStackTrace *stack_, uptr size_)
172 : ErrorBase(tid, 10, "pvalloc-overflow"),
173 stack(stack_),
174 size(size_) {}
175 void Print();
178 struct ErrorInvalidAllocationAlignment : ErrorBase {
179 const BufferedStackTrace *stack;
180 uptr alignment;
182 ErrorInvalidAllocationAlignment() = default; // (*)
183 ErrorInvalidAllocationAlignment(u32 tid, BufferedStackTrace *stack_,
184 uptr alignment_)
185 : ErrorBase(tid, 10, "invalid-allocation-alignment"),
186 stack(stack_),
187 alignment(alignment_) {}
188 void Print();
191 struct ErrorInvalidAlignedAllocAlignment : ErrorBase {
192 const BufferedStackTrace *stack;
193 uptr size;
194 uptr alignment;
196 ErrorInvalidAlignedAllocAlignment() = default; // (*)
197 ErrorInvalidAlignedAllocAlignment(u32 tid, BufferedStackTrace *stack_,
198 uptr size_, uptr alignment_)
199 : ErrorBase(tid, 10, "invalid-aligned-alloc-alignment"),
200 stack(stack_),
201 size(size_),
202 alignment(alignment_) {}
203 void Print();
206 struct ErrorInvalidPosixMemalignAlignment : ErrorBase {
207 const BufferedStackTrace *stack;
208 uptr alignment;
210 ErrorInvalidPosixMemalignAlignment() = default; // (*)
211 ErrorInvalidPosixMemalignAlignment(u32 tid, BufferedStackTrace *stack_,
212 uptr alignment_)
213 : ErrorBase(tid, 10, "invalid-posix-memalign-alignment"),
214 stack(stack_),
215 alignment(alignment_) {}
216 void Print();
219 struct ErrorAllocationSizeTooBig : ErrorBase {
220 const BufferedStackTrace *stack;
221 uptr user_size;
222 uptr total_size;
223 uptr max_size;
225 ErrorAllocationSizeTooBig() = default; // (*)
226 ErrorAllocationSizeTooBig(u32 tid, BufferedStackTrace *stack_,
227 uptr user_size_, uptr total_size_, uptr max_size_)
228 : ErrorBase(tid, 10, "allocation-size-too-big"),
229 stack(stack_),
230 user_size(user_size_),
231 total_size(total_size_),
232 max_size(max_size_) {}
233 void Print();
236 struct ErrorRssLimitExceeded : ErrorBase {
237 const BufferedStackTrace *stack;
239 ErrorRssLimitExceeded() = default; // (*)
240 ErrorRssLimitExceeded(u32 tid, BufferedStackTrace *stack_)
241 : ErrorBase(tid, 10, "rss-limit-exceeded"),
242 stack(stack_) {}
243 void Print();
246 struct ErrorOutOfMemory : ErrorBase {
247 const BufferedStackTrace *stack;
248 uptr requested_size;
250 ErrorOutOfMemory() = default; // (*)
251 ErrorOutOfMemory(u32 tid, BufferedStackTrace *stack_, uptr requested_size_)
252 : ErrorBase(tid, 10, "out-of-memory"),
253 stack(stack_),
254 requested_size(requested_size_) {}
255 void Print();
258 struct ErrorStringFunctionMemoryRangesOverlap : ErrorBase {
259 const BufferedStackTrace *stack;
260 uptr length1, length2;
261 AddressDescription addr1_description;
262 AddressDescription addr2_description;
263 const char *function;
265 ErrorStringFunctionMemoryRangesOverlap() = default; // (*)
266 ErrorStringFunctionMemoryRangesOverlap(u32 tid, BufferedStackTrace *stack_,
267 uptr addr1, uptr length1_, uptr addr2,
268 uptr length2_, const char *function_)
269 : ErrorBase(tid),
270 stack(stack_),
271 length1(length1_),
272 length2(length2_),
273 addr1_description(addr1, length1, /*shouldLockThreadRegistry=*/false),
274 addr2_description(addr2, length2, /*shouldLockThreadRegistry=*/false),
275 function(function_) {
276 char bug_type[100];
277 internal_snprintf(bug_type, sizeof(bug_type), "%s-param-overlap", function);
278 scariness.Clear();
279 scariness.Scare(10, bug_type);
281 void Print();
284 struct ErrorStringFunctionSizeOverflow : ErrorBase {
285 const BufferedStackTrace *stack;
286 AddressDescription addr_description;
287 uptr size;
289 ErrorStringFunctionSizeOverflow() = default; // (*)
290 ErrorStringFunctionSizeOverflow(u32 tid, BufferedStackTrace *stack_,
291 uptr addr, uptr size_)
292 : ErrorBase(tid, 10, "negative-size-param"),
293 stack(stack_),
294 addr_description(addr, /*shouldLockThreadRegistry=*/false),
295 size(size_) {}
296 void Print();
299 struct ErrorBadParamsToAnnotateContiguousContainer : ErrorBase {
300 const BufferedStackTrace *stack;
301 uptr beg, end, old_mid, new_mid;
303 ErrorBadParamsToAnnotateContiguousContainer() = default; // (*)
304 // PS4: Do we want an AddressDescription for beg?
305 ErrorBadParamsToAnnotateContiguousContainer(u32 tid,
306 BufferedStackTrace *stack_,
307 uptr beg_, uptr end_,
308 uptr old_mid_, uptr new_mid_)
309 : ErrorBase(tid, 10, "bad-__sanitizer_annotate_contiguous_container"),
310 stack(stack_),
311 beg(beg_),
312 end(end_),
313 old_mid(old_mid_),
314 new_mid(new_mid_) {}
315 void Print();
318 struct ErrorODRViolation : ErrorBase {
319 __asan_global global1, global2;
320 u32 stack_id1, stack_id2;
322 ErrorODRViolation() = default; // (*)
323 ErrorODRViolation(u32 tid, const __asan_global *g1, u32 stack_id1_,
324 const __asan_global *g2, u32 stack_id2_)
325 : ErrorBase(tid, 10, "odr-violation"),
326 global1(*g1),
327 global2(*g2),
328 stack_id1(stack_id1_),
329 stack_id2(stack_id2_) {}
330 void Print();
333 struct ErrorInvalidPointerPair : ErrorBase {
334 uptr pc, bp, sp;
335 AddressDescription addr1_description;
336 AddressDescription addr2_description;
338 ErrorInvalidPointerPair() = default; // (*)
339 ErrorInvalidPointerPair(u32 tid, uptr pc_, uptr bp_, uptr sp_, uptr p1,
340 uptr p2)
341 : ErrorBase(tid, 10, "invalid-pointer-pair"),
342 pc(pc_),
343 bp(bp_),
344 sp(sp_),
345 addr1_description(p1, 1, /*shouldLockThreadRegistry=*/false),
346 addr2_description(p2, 1, /*shouldLockThreadRegistry=*/false) {}
347 void Print();
350 struct ErrorGeneric : ErrorBase {
351 AddressDescription addr_description;
352 uptr pc, bp, sp;
353 uptr access_size;
354 const char *bug_descr;
355 bool is_write;
356 u8 shadow_val;
358 ErrorGeneric() = default; // (*)
359 ErrorGeneric(u32 tid, uptr addr, uptr pc_, uptr bp_, uptr sp_, bool is_write_,
360 uptr access_size_);
361 void Print();
364 // clang-format off
365 #define ASAN_FOR_EACH_ERROR_KIND(macro) \
366 macro(DeadlySignal) \
367 macro(DoubleFree) \
368 macro(NewDeleteTypeMismatch) \
369 macro(FreeNotMalloced) \
370 macro(AllocTypeMismatch) \
371 macro(MallocUsableSizeNotOwned) \
372 macro(SanitizerGetAllocatedSizeNotOwned) \
373 macro(CallocOverflow) \
374 macro(PvallocOverflow) \
375 macro(InvalidAllocationAlignment) \
376 macro(InvalidAlignedAllocAlignment) \
377 macro(InvalidPosixMemalignAlignment) \
378 macro(AllocationSizeTooBig) \
379 macro(RssLimitExceeded) \
380 macro(OutOfMemory) \
381 macro(StringFunctionMemoryRangesOverlap) \
382 macro(StringFunctionSizeOverflow) \
383 macro(BadParamsToAnnotateContiguousContainer) \
384 macro(ODRViolation) \
385 macro(InvalidPointerPair) \
386 macro(Generic)
387 // clang-format on
389 #define ASAN_DEFINE_ERROR_KIND(name) kErrorKind##name,
390 #define ASAN_ERROR_DESCRIPTION_MEMBER(name) Error##name name;
391 #define ASAN_ERROR_DESCRIPTION_CONSTRUCTOR(name) \
392 ErrorDescription(Error##name const &e) : kind(kErrorKind##name), name(e) {}
393 #define ASAN_ERROR_DESCRIPTION_PRINT(name) \
394 case kErrorKind##name: \
395 return name.Print();
397 enum ErrorKind {
398 kErrorKindInvalid = 0,
399 ASAN_FOR_EACH_ERROR_KIND(ASAN_DEFINE_ERROR_KIND)
402 struct ErrorDescription {
403 ErrorKind kind;
404 // We're using a tagged union because it allows us to have a trivially
405 // copiable type and use the same structures as the public interface.
407 // We can add a wrapper around it to make it "more c++-like", but that would
408 // add a lot of code and the benefit wouldn't be that big.
409 union {
410 ErrorBase Base;
411 ASAN_FOR_EACH_ERROR_KIND(ASAN_ERROR_DESCRIPTION_MEMBER)
414 ErrorDescription() { internal_memset(this, 0, sizeof(*this)); }
415 explicit ErrorDescription(LinkerInitialized) {}
416 ASAN_FOR_EACH_ERROR_KIND(ASAN_ERROR_DESCRIPTION_CONSTRUCTOR)
418 bool IsValid() { return kind != kErrorKindInvalid; }
419 void Print() {
420 switch (kind) {
421 ASAN_FOR_EACH_ERROR_KIND(ASAN_ERROR_DESCRIPTION_PRINT)
422 case kErrorKindInvalid:
423 CHECK(0);
425 CHECK(0);
429 #undef ASAN_FOR_EACH_ERROR_KIND
430 #undef ASAN_DEFINE_ERROR_KIND
431 #undef ASAN_ERROR_DESCRIPTION_MEMBER
432 #undef ASAN_ERROR_DESCRIPTION_CONSTRUCTOR
433 #undef ASAN_ERROR_DESCRIPTION_PRINT
435 } // namespace __asan
437 #endif // ASAN_ERRORS_H