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());
28 class AsanThreadIdAndName
{
30 explicit AsanThreadIdAndName(AsanThreadContext
*t
);
31 explicit AsanThreadIdAndName(u32 tid
);
33 // Contains "T%tid (%name)" or "T%tid" if the name is empty.
34 const char *c_str() const { return &name
[0]; }
37 void Init(u32 tid
, const char *tname
);
42 class Decorator
: public __sanitizer::SanitizerCommonDecorator
{
44 Decorator() : SanitizerCommonDecorator() {}
45 const char *Access() { return Blue(); }
46 const char *Location() { return Green(); }
47 const char *Allocation() { return Magenta(); }
49 const char *ShadowByte(u8 byte
) {
51 case kAsanHeapLeftRedzoneMagic
:
52 case kAsanArrayCookieMagic
:
54 case kAsanHeapFreeMagic
:
56 case kAsanStackLeftRedzoneMagic
:
57 case kAsanStackMidRedzoneMagic
:
58 case kAsanStackRightRedzoneMagic
:
60 case kAsanStackAfterReturnMagic
:
62 case kAsanInitializationOrderMagic
:
64 case kAsanUserPoisonedMemoryMagic
:
65 case kAsanContiguousContainerOOBMagic
:
66 case kAsanAllocaLeftMagic
:
67 case kAsanAllocaRightMagic
:
69 case kAsanStackUseAfterScopeMagic
:
71 case kAsanGlobalRedzoneMagic
:
73 case kAsanInternalHeapMagic
:
75 case kAsanIntraObjectRedzone
:
83 enum ShadowKind
: u8
{
88 static const char *const ShadowNames
[] = {"low shadow", "shadow gap",
91 struct ShadowAddressDescription
{
99 bool GetShadowAddressInformation(uptr addr
, ShadowAddressDescription
*descr
);
100 bool DescribeAddressIfShadow(uptr addr
);
106 kAccessTypeUnknown
, // This means we have an AddressSanitizer bug!
114 u32 user_requested_alignment
: 12;
119 struct HeapAddressDescription
{
125 ChunkAccess chunk_access
;
130 bool GetHeapAddressInformation(uptr addr
, uptr access_size
,
131 HeapAddressDescription
*descr
);
132 bool DescribeAddressIfHeap(uptr addr
, uptr access_size
= 1);
134 struct StackAddressDescription
{
140 const char *frame_descr
;
145 bool GetStackAddressInformation(uptr addr
, uptr access_size
,
146 StackAddressDescription
*descr
);
148 struct GlobalAddressDescription
{
150 // Assume address is close to at most four globals.
151 static const int kMaxGlobals
= 4;
152 __asan_global globals
[kMaxGlobals
];
153 u32 reg_sites
[kMaxGlobals
];
157 void Print(const char *bug_type
= "") const;
159 // Returns true when this descriptions points inside the same global variable
160 // as other. Descriptions can have different address within the variable
161 bool PointsInsideTheSameVariable(const GlobalAddressDescription
&other
) const;
164 bool GetGlobalAddressInformation(uptr addr
, uptr access_size
,
165 GlobalAddressDescription
*descr
);
166 bool DescribeAddressIfGlobal(uptr addr
, uptr access_size
, const char *bug_type
);
168 // General function to describe an address. Will try to describe the address as
169 // a shadow, global (variable), stack, or heap address.
170 // bug_type is optional and is used for checking if we're reporting an
171 // initialization-order-fiasco
172 // The proper access_size should be passed for stack, global, and heap
173 // addresses. Defaults to 1.
174 // Each of the *AddressDescription functions has its own Print() member, which
175 // may take access_size and bug_type parameters if needed.
176 void PrintAddressDescription(uptr addr
, uptr access_size
= 1,
177 const char *bug_type
= "");
187 class AddressDescription
{
188 struct AddressDescriptionData
{
191 ShadowAddressDescription shadow
;
192 HeapAddressDescription heap
;
193 StackAddressDescription stack
;
194 GlobalAddressDescription global
;
199 AddressDescriptionData data
;
202 AddressDescription() = default;
203 // shouldLockThreadRegistry allows us to skip locking if we're sure we already
205 AddressDescription(uptr addr
, bool shouldLockThreadRegistry
= true)
206 : AddressDescription(addr
, 1, shouldLockThreadRegistry
) {}
207 AddressDescription(uptr addr
, uptr access_size
,
208 bool shouldLockThreadRegistry
= true);
210 uptr
Address() const {
212 case kAddressKindWild
:
214 case kAddressKindShadow
:
215 return data
.shadow
.addr
;
216 case kAddressKindHeap
:
217 return data
.heap
.addr
;
218 case kAddressKindStack
:
219 return data
.stack
.addr
;
220 case kAddressKindGlobal
:
221 return data
.global
.addr
;
223 UNREACHABLE("AddressInformation kind is invalid");
225 void Print(const char *bug_descr
= nullptr) const {
227 case kAddressKindWild
:
228 Printf("Address %p is a wild pointer.\n", data
.addr
);
230 case kAddressKindShadow
:
231 return data
.shadow
.Print();
232 case kAddressKindHeap
:
233 return data
.heap
.Print();
234 case kAddressKindStack
:
235 return data
.stack
.Print();
236 case kAddressKindGlobal
:
237 // initialization-order-fiasco has a special Print()
238 return data
.global
.Print(bug_descr
);
240 UNREACHABLE("AddressInformation kind is invalid");
243 void StoreTo(AddressDescriptionData
*dst
) const { *dst
= data
; }
245 const ShadowAddressDescription
*AsShadow() const {
246 return data
.kind
== kAddressKindShadow
? &data
.shadow
: nullptr;
248 const HeapAddressDescription
*AsHeap() const {
249 return data
.kind
== kAddressKindHeap
? &data
.heap
: nullptr;
251 const StackAddressDescription
*AsStack() const {
252 return data
.kind
== kAddressKindStack
? &data
.stack
: nullptr;
254 const GlobalAddressDescription
*AsGlobal() const {
255 return data
.kind
== kAddressKindGlobal
? &data
.global
: nullptr;
259 } // namespace __asan
261 #endif // ASAN_DESCRIPTIONS_H