Index: lib/asan/asan_descriptions.h =================================================================== --- lib/asan/asan_descriptions.h +++ lib/asan/asan_descriptions.h @@ -165,6 +165,88 @@ void PrintAddressDescription(uptr addr, uptr access_size = 1, const char *bug_type = ""); +enum AddressKind { + kAddressKindWild, + kAddressKindShadow, + kAddressKindHeap, + kAddressKindStack, + kAddressKindGlobal, +}; + +struct NewAddressDescriptionBase { + AddressKind kind; + union { + ShadowAddressDescription shadow; + HeapAddressDescription heap; + StackAddressDescription stack; + GlobalAddressDescription global; + uptr addr; + }; + uptr Address() { + switch (kind) { + case kAddressKindWild: + return addr; + case kAddressKindShadow: + return shadow.addr; + case kAddressKindHeap: + return heap.addr; + case kAddressKindStack: + return stack.addr; + case kAddressKindGlobal: + return global.addr; + } + } + void Print() { + switch (kind) { + case kAddressKindWild: + Printf("Address %p is a wild pointer.\n", addr); + return; + case kAddressKindShadow: + return shadow.Print(); + case kAddressKindHeap: + return heap.Print(); + case kAddressKindStack: + return stack.Print(); + case kAddressKindGlobal: + return global.Print(); + } + } +}; + +struct NewAddressDescription : NewAddressDescriptionBase { + NewAddressDescription() { + kind = kAddressKindWild; + addr = 0; + } + // shouldLockThreadRegistry allows us to skip locking if we're sure we already + // have it. + NewAddressDescription(uptr addr, bool shouldLockThreadRegistry = true) { + if (GetShadowAddressInformation(addr, &shadow)) { + kind = kAddressKindShadow; + return; + } + if (GetHeapAddressInformation(addr, 1, &heap)) { + kind = kAddressKindHeap; + return; + } + + if (shouldLockThreadRegistry) asanThreadRegistry().Lock(); + if (GetStackAddressInformation(addr, &stack)) { + kind = kAddressKindStack; + if (shouldLockThreadRegistry) asanThreadRegistry().Unlock(); + return; + } + if (shouldLockThreadRegistry) asanThreadRegistry().Unlock(); + + if (GetGlobalAddressInformation(addr, &global)) { + kind = kAddressKindGlobal; + return; + } + kind = kAddressKindWild; + addr = 0; + } +}; + } // namespace __asan #endif // ASAN_DESCRIPTIONS_H