]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/compiler-rt/lib/hwasan/hwasan_report.cc
Merge clang 7.0.1 and several follow-up changes
[FreeBSD/FreeBSD.git] / contrib / compiler-rt / lib / hwasan / hwasan_report.cc
1 //===-- hwasan_report.cc --------------------------------------------------===//
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 // Error reporting.
13 //===----------------------------------------------------------------------===//
14
15 #include "hwasan.h"
16 #include "hwasan_allocator.h"
17 #include "hwasan_mapping.h"
18 #include "sanitizer_common/sanitizer_allocator_internal.h"
19 #include "sanitizer_common/sanitizer_common.h"
20 #include "sanitizer_common/sanitizer_flags.h"
21 #include "sanitizer_common/sanitizer_mutex.h"
22 #include "sanitizer_common/sanitizer_report_decorator.h"
23 #include "sanitizer_common/sanitizer_stackdepot.h"
24 #include "sanitizer_common/sanitizer_symbolizer.h"
25
26 using namespace __sanitizer;
27
28 namespace __hwasan {
29
30 static StackTrace GetStackTraceFromId(u32 id) {
31   CHECK(id);
32   StackTrace res = StackDepotGet(id);
33   CHECK(res.trace);
34   return res;
35 }
36
37 class Decorator: public __sanitizer::SanitizerCommonDecorator {
38  public:
39   Decorator() : SanitizerCommonDecorator() { }
40   const char *Allocation() const { return Magenta(); }
41   const char *Origin() const { return Magenta(); }
42   const char *Name() const { return Green(); }
43 };
44
45 struct HeapAddressDescription {
46   uptr addr;
47   u32 alloc_stack_id;
48   u32 free_stack_id;
49
50   void Print() const {
51     Decorator d;
52     if (free_stack_id) {
53       Printf("%sfreed here:%s\n", d.Allocation(), d.Default());
54       GetStackTraceFromId(free_stack_id).Print();
55       Printf("%spreviously allocated here:%s\n", d.Allocation(), d.Default());
56     } else {
57       Printf("%sallocated here:%s\n", d.Allocation(), d.Default());
58     }
59     GetStackTraceFromId(alloc_stack_id).Print();
60   }
61 };
62
63 bool GetHeapAddressInformation(uptr addr, uptr access_size,
64                                HeapAddressDescription *description) {
65   HwasanChunkView chunk = FindHeapChunkByAddress(addr);
66   if (!chunk.IsValid())
67     return false;
68   description->addr = addr;
69   description->alloc_stack_id = chunk.GetAllocStackId();
70   description->free_stack_id = chunk.GetFreeStackId();
71   return true;
72 }
73
74 void PrintAddressDescription(uptr addr, uptr access_size) {
75   HeapAddressDescription heap_description;
76   if (GetHeapAddressInformation(addr, access_size, &heap_description)) {
77     heap_description.Print();
78     return;
79   }
80   // We exhausted our possibilities. Bail out.
81   Printf("HWAddressSanitizer can not describe address in more detail.\n");
82 }
83
84 void ReportInvalidAccess(StackTrace *stack, u32 origin) {
85   ScopedErrorReportLock l;
86
87   Decorator d;
88   Printf("%s", d.Warning());
89   Report("WARNING: HWAddressSanitizer: invalid access\n");
90   Printf("%s", d.Default());
91   stack->Print();
92   ReportErrorSummary("invalid-access", stack);
93 }
94
95 void ReportStats() {}
96
97 void ReportInvalidAccessInsideAddressRange(const char *what, const void *start,
98                                            uptr size, uptr offset) {
99   ScopedErrorReportLock l;
100
101   Decorator d;
102   Printf("%s", d.Warning());
103   Printf("%sTag mismatch in %s%s%s at offset %zu inside [%p, %zu)%s\n",
104          d.Warning(), d.Name(), what, d.Warning(), offset, start, size,
105          d.Default());
106   PrintAddressDescription((uptr)start + offset, 1);
107   // if (__sanitizer::Verbosity())
108   //   DescribeMemoryRange(start, size);
109 }
110
111 void ReportTagMismatch(StackTrace *stack, uptr addr, uptr access_size,
112                        bool is_store) {
113   ScopedErrorReportLock l;
114
115   Decorator d;
116   Printf("%s", d.Warning());
117   uptr address = GetAddressFromPointer(addr);
118   Printf("%s of size %zu at %p\n", is_store ? "WRITE" : "READ", access_size,
119          address);
120
121   tag_t ptr_tag = GetTagFromPointer(addr);
122   tag_t mem_tag = *(tag_t *)MEM_TO_SHADOW(address);
123   Printf("pointer tag 0x%x\nmemory tag  0x%x\n", ptr_tag, mem_tag);
124   Printf("%s", d.Default());
125
126   stack->Print();
127
128   PrintAddressDescription(address, access_size);
129
130   ReportErrorSummary("tag-mismatch", stack);
131 }
132
133 }  // namespace __hwasan