1 //===-- asan_descriptions.h -------------------------------------*- C++ -*-===//
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
6 //===----------------------------------------------------------------------===//
8 // This file is a part of AddressSanitizer, an address sanity checker.
10 // ASan-private header for asan_descriptions.cc.
11 // TODO(filcab): Most struct definitions should move to the interface headers.
12 //===----------------------------------------------------------------------===//
13 #ifndef ASAN_DESCRIPTIONS_H
14 #define ASAN_DESCRIPTIONS_H
16 #include "asan_allocator.h"
17 #include "asan_thread.h"
18 #include "sanitizer_common/sanitizer_common.h"
19 #include "sanitizer_common/sanitizer_report_decorator.h"
23 void DescribeThread(AsanThreadContext
*context
);
24 static inline void DescribeThread(AsanThread
*t
) {
25 if (t
) DescribeThread(t
->context());
27 const char *ThreadNameWithParenthesis(AsanThreadContext
*t
, char buff
[],
29 const char *ThreadNameWithParenthesis(u32 tid
, char buff
[], uptr buff_len
);
31 class Decorator
: public __sanitizer::SanitizerCommonDecorator
{
33 Decorator() : SanitizerCommonDecorator() {}
34 const char *Access() { return Blue(); }
35 const char *EndAccess() { return Default(); }
36 const char *Location() { return Green(); }
37 const char *EndLocation() { return Default(); }
38 const char *Allocation() { return Magenta(); }
39 const char *EndAllocation() { return Default(); }
41 const char *ShadowByte(u8 byte
) {
43 case kAsanHeapLeftRedzoneMagic
:
44 case kAsanArrayCookieMagic
:
46 case kAsanHeapFreeMagic
:
48 case kAsanStackLeftRedzoneMagic
:
49 case kAsanStackMidRedzoneMagic
:
50 case kAsanStackRightRedzoneMagic
:
52 case kAsanStackAfterReturnMagic
:
54 case kAsanInitializationOrderMagic
:
56 case kAsanUserPoisonedMemoryMagic
:
57 case kAsanContiguousContainerOOBMagic
:
58 case kAsanAllocaLeftMagic
:
59 case kAsanAllocaRightMagic
:
61 case kAsanStackUseAfterScopeMagic
:
63 case kAsanGlobalRedzoneMagic
:
65 case kAsanInternalHeapMagic
:
67 case kAsanIntraObjectRedzone
:
73 const char *EndShadowByte() { return Default(); }
74 const char *MemoryByte() { return Magenta(); }
75 const char *EndMemoryByte() { return Default(); }
78 enum ShadowKind
: u8
{
83 static const char *const ShadowNames
[] = {"low shadow", "shadow gap",
86 struct ShadowAddressDescription
{
94 bool GetShadowAddressInformation(uptr addr
, ShadowAddressDescription
*descr
);
95 bool DescribeAddressIfShadow(uptr addr
);
101 kAccessTypeUnknown
, // This means we have an AddressSanitizer bug!
113 struct HeapAddressDescription
{
119 ChunkAccess chunk_access
;
124 bool GetHeapAddressInformation(uptr addr
, uptr access_size
,
125 HeapAddressDescription
*descr
);
126 bool DescribeAddressIfHeap(uptr addr
, uptr access_size
= 1);
128 struct StackAddressDescription
{
134 const char *frame_descr
;
139 bool GetStackAddressInformation(uptr addr
, uptr access_size
,
140 StackAddressDescription
*descr
);
142 struct GlobalAddressDescription
{
144 // Assume address is close to at most four globals.
145 static const int kMaxGlobals
= 4;
146 __asan_global globals
[kMaxGlobals
];
147 u32 reg_sites
[kMaxGlobals
];
151 void Print(const char *bug_type
= "") const;
154 bool GetGlobalAddressInformation(uptr addr
, uptr access_size
,
155 GlobalAddressDescription
*descr
);
156 bool DescribeAddressIfGlobal(uptr addr
, uptr access_size
, const char *bug_type
);
158 // General function to describe an address. Will try to describe the address as
159 // a shadow, global (variable), stack, or heap address.
160 // bug_type is optional and is used for checking if we're reporting an
161 // initialization-order-fiasco
162 // The proper access_size should be passed for stack, global, and heap
163 // addresses. Defaults to 1.
164 // Each of the *AddressDescription functions has its own Print() member, which
165 // may take access_size and bug_type parameters if needed.
166 void PrintAddressDescription(uptr addr
, uptr access_size
= 1,
167 const char *bug_type
= "");
177 class AddressDescription
{
178 struct AddressDescriptionData
{
181 ShadowAddressDescription shadow
;
182 HeapAddressDescription heap
;
183 StackAddressDescription stack
;
184 GlobalAddressDescription global
;
189 AddressDescriptionData data
;
192 AddressDescription() = default;
193 // shouldLockThreadRegistry allows us to skip locking if we're sure we already
195 AddressDescription(uptr addr
, bool shouldLockThreadRegistry
= true)
196 : AddressDescription(addr
, 1, shouldLockThreadRegistry
) {}
197 AddressDescription(uptr addr
, uptr access_size
,
198 bool shouldLockThreadRegistry
= true);
200 uptr
Address() const {
202 case kAddressKindWild
:
204 case kAddressKindShadow
:
205 return data
.shadow
.addr
;
206 case kAddressKindHeap
:
207 return data
.heap
.addr
;
208 case kAddressKindStack
:
209 return data
.stack
.addr
;
210 case kAddressKindGlobal
:
211 return data
.global
.addr
;
213 UNREACHABLE("AddressInformation kind is invalid");
215 void Print(const char *bug_descr
= nullptr) const {
217 case kAddressKindWild
:
218 Printf("Address %p is a wild pointer.\n", data
.addr
);
220 case kAddressKindShadow
:
221 return data
.shadow
.Print();
222 case kAddressKindHeap
:
223 return data
.heap
.Print();
224 case kAddressKindStack
:
225 return data
.stack
.Print();
226 case kAddressKindGlobal
:
227 // initialization-order-fiasco has a special Print()
228 return data
.global
.Print(bug_descr
);
230 UNREACHABLE("AddressInformation kind is invalid");
233 void StoreTo(AddressDescriptionData
*dst
) const { *dst
= data
; }
235 const ShadowAddressDescription
*AsShadow() const {
236 return data
.kind
== kAddressKindShadow
? &data
.shadow
: nullptr;
238 const HeapAddressDescription
*AsHeap() const {
239 return data
.kind
== kAddressKindHeap
? &data
.heap
: nullptr;
241 const StackAddressDescription
*AsStack() const {
242 return data
.kind
== kAddressKindStack
? &data
.stack
: nullptr;
244 const GlobalAddressDescription
*AsGlobal() const {
245 return data
.kind
== kAddressKindGlobal
? &data
.global
: nullptr;
249 } // namespace __asan
251 #endif // ASAN_DESCRIPTIONS_H