From f8a15c3b5729adeb70977641af167d265b4cb04b Mon Sep 17 00:00:00 2001 From: Filipe Cabecinhas Date: Mon, 15 Aug 2016 19:30:21 +0000 Subject: [PATCH] Split DescribeAddressIfShadow between a function that gets all the information, and one that prints it. Summary: Replacement for part of D23518 This is the first patch to start reifying information about errors. It deals only with reifying shadow address-related information. It will allow us to generate structures with all the relevant information for a given error so a debugger can get to them or they can be included in a core dump. Reviewers: kcc, samsonov Subscribers: kubabrecka, llvm-commits Differential Revision: https://reviews.llvm.org/D23519 llvm-svn: 278718 --- compiler-rt/lib/asan/CMakeLists.txt | 1 + compiler-rt/lib/asan/asan_debugging.cc | 5 ++- compiler-rt/lib/asan/asan_descriptions.cc | 54 +++++++++++++++++++++++++++++++ compiler-rt/lib/asan/asan_descriptions.h | 37 +++++++++++++++++++++ compiler-rt/lib/asan/asan_report.cc | 21 +----------- compiler-rt/lib/asan/asan_report.h | 2 -- 6 files changed, 97 insertions(+), 23 deletions(-) create mode 100644 compiler-rt/lib/asan/asan_descriptions.cc create mode 100644 compiler-rt/lib/asan/asan_descriptions.h diff --git a/compiler-rt/lib/asan/CMakeLists.txt b/compiler-rt/lib/asan/CMakeLists.txt index b7e41fc..7325932 100644 --- a/compiler-rt/lib/asan/CMakeLists.txt +++ b/compiler-rt/lib/asan/CMakeLists.txt @@ -4,6 +4,7 @@ set(ASAN_SOURCES asan_allocator.cc asan_activation.cc asan_debugging.cc + asan_descriptions.cc asan_fake_stack.cc asan_flags.cc asan_globals.cc diff --git a/compiler-rt/lib/asan/asan_debugging.cc b/compiler-rt/lib/asan/asan_debugging.cc index 7c3a8a7..b7481ff 100644 --- a/compiler-rt/lib/asan/asan_debugging.cc +++ b/compiler-rt/lib/asan/asan_debugging.cc @@ -14,6 +14,7 @@ //===----------------------------------------------------------------------===// #include "asan_allocator.h" +#include "asan_descriptions.h" #include "asan_flags.h" #include "asan_internal.h" #include "asan_mapping.h" @@ -65,7 +66,9 @@ void GetInfoForHeapAddress(uptr addr, AddressDescription *descr) { } void AsanLocateAddress(uptr addr, AddressDescription *descr) { - if (DescribeAddressIfShadow(addr, descr, /* print */ false)) { + ShadowAddressDescription shadow_descr; + if (GetShadowAddressInformation(addr, &shadow_descr)) { + descr->region_kind = ShadowNames[shadow_descr.kind]; return; } if (GetInfoForAddressIfGlobal(addr, descr)) { diff --git a/compiler-rt/lib/asan/asan_descriptions.cc b/compiler-rt/lib/asan/asan_descriptions.cc new file mode 100644 index 0000000..9fc52a4 --- /dev/null +++ b/compiler-rt/lib/asan/asan_descriptions.cc @@ -0,0 +1,54 @@ +//===-- asan_descriptions.cc ------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is a part of AddressSanitizer, an address sanity checker. +// +// ASan functions for getting information about an address and/or printing it. +//===----------------------------------------------------------------------===// + +#include "asan_descriptions.h" +#include "asan_mapping.h" + +namespace __asan { + +// Shadow descriptions +static bool GetShadowKind(uptr addr, ShadowKind *shadow_kind) { + CHECK(!AddrIsInMem(addr)); + if (AddrIsInShadowGap(addr)) { + *shadow_kind = kShadowKindGap; + } else if (AddrIsInHighShadow(addr)) { + *shadow_kind = kShadowKindHigh; + } else if (AddrIsInLowShadow(addr)) { + *shadow_kind = kShadowKindLow; + } else { + CHECK(0 && "Address is not in memory and not in shadow?"); + return false; + } + return true; +} + +bool DescribeAddressIfShadow(uptr addr) { + ShadowAddressDescription descr; + if (!GetShadowAddressInformation(addr, &descr)) return false; + Printf("Address %p is located in the %s area.\n", addr, + ShadowNames[descr.kind]); + return true; +} + +bool GetShadowAddressInformation(uptr addr, ShadowAddressDescription *descr) { + if (AddrIsInMem(addr)) return false; + ShadowKind shadow_kind; + if (!GetShadowKind(addr, &shadow_kind)) return false; + if (shadow_kind != kShadowKindGap) descr->shadow_byte = *(u8 *)addr; + descr->addr = addr; + descr->kind = shadow_kind; + return true; +} + +} // namespace __asan diff --git a/compiler-rt/lib/asan/asan_descriptions.h b/compiler-rt/lib/asan/asan_descriptions.h new file mode 100644 index 0000000..c96fef9 --- /dev/null +++ b/compiler-rt/lib/asan/asan_descriptions.h @@ -0,0 +1,37 @@ +//===-- asan_descriptions.h -------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is a part of AddressSanitizer, an address sanity checker. +// +// ASan-private header for asan_descriptions.cc. +// TODO(filcab): Most struct definitions should move to the interface headers. +//===----------------------------------------------------------------------===// + +#include "sanitizer_common/sanitizer_common.h" + +namespace __asan { + +enum ShadowKind : u8 { + kShadowKindLow, + kShadowKindGap, + kShadowKindHigh, +}; +static const char *const ShadowNames[] = {"low shadow", "shadow gap", + "high shadow"}; + +struct ShadowAddressDescription { + uptr addr; + ShadowKind kind; + u8 shadow_byte; +}; + +bool GetShadowAddressInformation(uptr addr, ShadowAddressDescription *descr); +bool DescribeAddressIfShadow(uptr addr); + +} // namespace __asan diff --git a/compiler-rt/lib/asan/asan_report.cc b/compiler-rt/lib/asan/asan_report.cc index afdd4ea..7b632ac 100644 --- a/compiler-rt/lib/asan/asan_report.cc +++ b/compiler-rt/lib/asan/asan_report.cc @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "asan_flags.h" +#include "asan_descriptions.h" #include "asan_internal.h" #include "asan_mapping.h" #include "asan_report.h" @@ -336,26 +337,6 @@ static bool DescribeAddressIfGlobal(uptr addr, uptr size, return true; } -bool DescribeAddressIfShadow(uptr addr, AddressDescription *descr, bool print) { - if (AddrIsInMem(addr)) - return false; - const char *area_type = nullptr; - if (AddrIsInShadowGap(addr)) area_type = "shadow gap"; - else if (AddrIsInHighShadow(addr)) area_type = "high shadow"; - else if (AddrIsInLowShadow(addr)) area_type = "low shadow"; - if (area_type != nullptr) { - if (print) { - Printf("Address %p is located in the %s area.\n", addr, area_type); - } else { - CHECK(descr); - descr->region_kind = area_type; - } - return true; - } - CHECK(0 && "Address is not in memory and not in shadow?"); - return false; -} - // Return " (thread_name) " or an empty string if the name is empty. const char *ThreadNameWithParenthesis(AsanThreadContext *t, char buff[], uptr buff_len) { diff --git a/compiler-rt/lib/asan/asan_report.h b/compiler-rt/lib/asan/asan_report.h index 03f0965..377bc3d 100644 --- a/compiler-rt/lib/asan/asan_report.h +++ b/compiler-rt/lib/asan/asan_report.h @@ -41,8 +41,6 @@ bool GetInfoForAddressIfGlobal(uptr addr, AddressDescription *descr); // The following functions prints address description depending // on the memory type (shadow/heap/stack/global). void DescribeHeapAddress(uptr addr, uptr access_size); -bool DescribeAddressIfShadow(uptr addr, AddressDescription *descr = nullptr, - bool print = true); bool ParseFrameDescription(const char *frame_descr, InternalMmapVector *vars); bool DescribeAddressIfStack(uptr addr, uptr access_size); -- 2.7.4