[compiler-rt] r281090 - [asan] Add a new AddressDescription structure, which can describe any type of address.

Filipe Cabecinhas via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 9 13:43:21 PDT 2016


Author: filcab
Date: Fri Sep  9 15:43:20 2016
New Revision: 281090

URL: http://llvm.org/viewvc/llvm-project?rev=281090&view=rev
Log:
[asan] Add a new AddressDescription structure, which can describe any type of address.

Summary:
This is useful for inclusion in the Error* structures, to describe an
arbitrary address.

Remove the old struct since it's used only once. This removes one level of
indirection, and moves all *AddressDescription to be one of the recently
introduced structures.

This merges differential revisions: D24131 and D24132

Reviewers: kcc, eugenis, vitalybuka

Subscribers: kubabrecka, llvm-commits

Differential Revision: https://reviews.llvm.org/D24131

Modified:
    compiler-rt/trunk/lib/asan/asan_debugging.cc
    compiler-rt/trunk/lib/asan/asan_descriptions.cc
    compiler-rt/trunk/lib/asan/asan_descriptions.h
    compiler-rt/trunk/lib/asan/asan_report.h

Modified: compiler-rt/trunk/lib/asan/asan_debugging.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_debugging.cc?rev=281090&r1=281089&r2=281090&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_debugging.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_debugging.cc Fri Sep  9 15:43:20 2016
@@ -24,8 +24,9 @@
 namespace {
 using namespace __asan;
 
-void FindInfoForStackVar(uptr addr, const char *frame_descr, uptr offset,
-                         AddressDescription *descr) {
+static void FindInfoForStackVar(uptr addr, const char *frame_descr, uptr offset,
+                                char *name, uptr name_size,
+                                uptr &region_address, uptr &region_size) {
   InternalMmapVector<StackVarDescr> vars(16);
   if (!ParseFrameDescription(frame_descr, &vars)) {
     return;
@@ -36,62 +37,15 @@ void FindInfoForStackVar(uptr addr, cons
       // We use name_len + 1 because strlcpy will guarantee a \0 at the end, so
       // if we're limiting the copy due to name_len, we add 1 to ensure we copy
       // the whole name and then terminate with '\0'.
-      internal_strlcpy(descr->name, vars[i].name_pos,
-                       Min(descr->name_size, vars[i].name_len + 1));
-      descr->region_address = addr - (offset - vars[i].beg);
-      descr->region_size = vars[i].size;
+      internal_strlcpy(name, vars[i].name_pos,
+                       Min(name_size, vars[i].name_len + 1));
+      region_address = addr - (offset - vars[i].beg);
+      region_size = vars[i].size;
       return;
     }
   }
 }
 
-void AsanLocateAddress(uptr addr, AddressDescription *descr) {
-  ShadowAddressDescription shadow_descr;
-  if (GetShadowAddressInformation(addr, &shadow_descr)) {
-    descr->region_kind = ShadowNames[shadow_descr.kind];
-    return;
-  }
-  GlobalAddressDescription global_descr;
-  if (GetGlobalAddressInformation(addr, &global_descr)) {
-    descr->region_kind = "global";
-    auto &g = global_descr.globals[0];
-    internal_strlcpy(descr->name, g.name, descr->name_size);
-    descr->region_address = g.beg;
-    descr->region_size = g.size;
-    return;
-  }
-
-  StackAddressDescription stack_descr;
-  asanThreadRegistry().Lock();
-  if (GetStackAddressInformation(addr, &stack_descr)) {
-    asanThreadRegistry().Unlock();
-    descr->region_kind = "stack";
-    if (!stack_descr.frame_descr) {
-      descr->name[0] = 0;
-      descr->region_address = 0;
-      descr->region_size = 0;
-    } else {
-      FindInfoForStackVar(addr, stack_descr.frame_descr, stack_descr.offset,
-                          descr);
-    }
-    return;
-  }
-  asanThreadRegistry().Unlock();
-
-  descr->name[0] = 0;
-  HeapAddressDescription heap_descr;
-  if (GetHeapAddressInformation(addr, 1, &heap_descr)) {
-    descr->region_address = heap_descr.chunk_access.chunk_begin;
-    descr->region_size = heap_descr.chunk_access.chunk_size;
-    descr->region_kind = "heap";
-    return;
-  }
-
-  descr->region_address = 0;
-  descr->region_size = 0;
-  descr->region_kind = "heap-invalid";
-}
-
 uptr AsanGetStack(uptr addr, uptr *trace, u32 size, u32 *thread_id,
                          bool alloc_stack) {
   AsanChunkView chunk = FindHeapChunkByAddress(addr);
@@ -123,12 +77,54 @@ uptr AsanGetStack(uptr addr, uptr *trace
 
 SANITIZER_INTERFACE_ATTRIBUTE
 const char *__asan_locate_address(uptr addr, char *name, uptr name_size,
-                                  uptr *region_address, uptr *region_size) {
-  AddressDescription descr = { name, name_size, 0, 0, nullptr };
-  AsanLocateAddress(addr, &descr);
-  if (region_address) *region_address = descr.region_address;
-  if (region_size) *region_size = descr.region_size;
-  return descr.region_kind;
+                                  uptr *region_address_ptr,
+                                  uptr *region_size_ptr) {
+  AddressDescription descr(addr);
+  uptr region_address = 0;
+  uptr region_size = 0;
+  const char *region_kind = nullptr;
+  if (name && name_size > 0) name[0] = 0;
+
+  if (auto shadow = descr.AsShadow()) {
+    // region_{address,size} are already 0
+    switch (shadow->kind) {
+      case kShadowKindLow:
+        region_kind = "low shadow";
+        break;
+      case kShadowKindGap:
+        region_kind = "shadow gap";
+        break;
+      case kShadowKindHigh:
+        region_kind = "high shadow";
+        break;
+    }
+  } else if (auto heap = descr.AsHeap()) {
+    region_kind = "heap";
+    region_address = heap->chunk_access.chunk_begin;
+    region_size = heap->chunk_access.chunk_size;
+  } else if (auto stack = descr.AsStack()) {
+    region_kind = "stack";
+    if (!stack->frame_descr) {
+      // region_{address,size} are already 0
+    } else {
+      FindInfoForStackVar(addr, stack->frame_descr, stack->offset, name,
+                          name_size, region_address, region_size);
+    }
+  } else if (auto global = descr.AsGlobal()) {
+    region_kind = "global";
+    auto &g = global->globals[0];
+    internal_strlcpy(name, g.name, name_size);
+    region_address = g.beg;
+    region_size = g.size;
+  } else {
+    // region_{address,size} are already 0
+    region_kind = "heap-invalid";
+  }
+
+  CHECK(region_kind);
+  if (region_address_ptr) *region_address_ptr = region_address;
+  if (region_size_ptr) *region_size_ptr = region_size;
+  return region_kind;
 }
 
 SANITIZER_INTERFACE_ATTRIBUTE

Modified: compiler-rt/trunk/lib/asan/asan_descriptions.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_descriptions.cc?rev=281090&r1=281089&r2=281090&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_descriptions.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_descriptions.cc Fri Sep  9 15:43:20 2016
@@ -312,11 +312,12 @@ bool DescribeAddressIfGlobal(uptr addr,
   return true;
 }
 
-void ShadowAddressDescription::Print() {
+void ShadowAddressDescription::Print() const {
   Printf("Address %p is located in the %s area.\n", addr, ShadowNames[kind]);
 }
 
-void GlobalAddressDescription::Print(uptr access_size, const char *bug_type) {
+void GlobalAddressDescription::Print(uptr access_size,
+                                     const char *bug_type) const {
   for (int i = 0; i < size; i++) {
     DescribeAddressRelativeToGlobal(addr, access_size, globals[i]);
     if (0 == internal_strcmp(bug_type, "initialization-order-fiasco") &&
@@ -327,7 +328,7 @@ void GlobalAddressDescription::Print(upt
   }
 }
 
-void StackAddressDescription::Print(uptr access_size) {
+void StackAddressDescription::Print(uptr access_size) const {
   Decorator d;
   char tname[128];
   Printf("%s", d.Location());
@@ -382,7 +383,7 @@ void StackAddressDescription::Print(uptr
   DescribeThread(GetThreadContextByTidLocked(tid));
 }
 
-void HeapAddressDescription::Print() {
+void HeapAddressDescription::Print() const {
   PrintHeapChunkAccess(addr, chunk_access);
 
   asanThreadRegistry().CheckLocked();
@@ -416,6 +417,37 @@ void HeapAddressDescription::Print() {
   DescribeThread(alloc_thread);
 }
 
+AddressDescription::AddressDescription(uptr addr, uptr access_size,
+                                       bool shouldLockThreadRegistry) {
+  if (GetShadowAddressInformation(addr, &data.shadow)) {
+    data.kind = kAddressKindShadow;
+    return;
+  }
+  if (GetHeapAddressInformation(addr, access_size, &data.heap)) {
+    data.kind = kAddressKindHeap;
+    return;
+  }
+
+  bool isStackMemory = false;
+  if (shouldLockThreadRegistry) {
+    ThreadRegistryLock l(&asanThreadRegistry());
+    isStackMemory = GetStackAddressInformation(addr, &data.stack);
+  } else {
+    isStackMemory = GetStackAddressInformation(addr, &data.stack);
+  }
+  if (isStackMemory) {
+    data.kind = kAddressKindStack;
+    return;
+  }
+
+  if (GetGlobalAddressInformation(addr, &data.global)) {
+    data.kind = kAddressKindGlobal;
+    return;
+  }
+  data.kind = kAddressKindWild;
+  addr = 0;
+}
+
 void PrintAddressDescription(uptr addr, uptr access_size,
                              const char *bug_type) {
   ShadowAddressDescription shadow_descr;

Modified: compiler-rt/trunk/lib/asan/asan_descriptions.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_descriptions.h?rev=281090&r1=281089&r2=281090&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_descriptions.h (original)
+++ compiler-rt/trunk/lib/asan/asan_descriptions.h Fri Sep  9 15:43:20 2016
@@ -90,7 +90,7 @@ struct ShadowAddressDescription {
   ShadowKind kind;
   u8 shadow_byte;
 
-  void Print();
+  void Print() const;
 };
 
 bool GetShadowAddressInformation(uptr addr, ShadowAddressDescription *descr);
@@ -120,7 +120,7 @@ struct HeapAddressDescription {
   u32 free_stack_id;
   ChunkAccess chunk_access;
 
-  void Print();
+  void Print() const;
 };
 
 bool GetHeapAddressInformation(uptr addr, uptr access_size,
@@ -134,11 +134,10 @@ struct StackAddressDescription {
   uptr frame_pc;
   const char *frame_descr;
 
-  void Print(uptr access_size = 1);
+  void Print(uptr access_size = 1) const;
 };
 
 bool GetStackAddressInformation(uptr addr, StackAddressDescription *descr);
-bool DescribeAddressIfStack(uptr addr, uptr access_size);
 
 struct GlobalAddressDescription {
   uptr addr;
@@ -148,7 +147,7 @@ struct GlobalAddressDescription {
   u32 reg_sites[kMaxGlobals];
   u8 size;
 
-  void Print(uptr access_size = 1, const char *bug_type = "");
+  void Print(uptr access_size = 1, const char *bug_type = "") const;
 };
 
 bool GetGlobalAddressInformation(uptr addr, GlobalAddressDescription *descr);
@@ -165,6 +164,85 @@ bool DescribeAddressIfGlobal(uptr addr,
 void PrintAddressDescription(uptr addr, uptr access_size = 1,
                              const char *bug_type = "");
 
+enum AddressKind {
+  kAddressKindWild,
+  kAddressKindShadow,
+  kAddressKindHeap,
+  kAddressKindStack,
+  kAddressKindGlobal,
+};
+
+class AddressDescription {
+  struct AddressDescriptionData {
+    AddressKind kind;
+    union {
+      ShadowAddressDescription shadow;
+      HeapAddressDescription heap;
+      StackAddressDescription stack;
+      GlobalAddressDescription global;
+      uptr addr;
+    };
+  };
+
+  AddressDescriptionData data;
+
+ public:
+  AddressDescription() = default;
+  // shouldLockThreadRegistry allows us to skip locking if we're sure we already
+  // have done it.
+  AddressDescription(uptr addr, bool shouldLockThreadRegistry = true)
+      : AddressDescription(addr, 1, shouldLockThreadRegistry) {}
+  AddressDescription(uptr addr, uptr access_size,
+                     bool shouldLockThreadRegistry = true);
+
+  uptr Address() const {
+    switch (data.kind) {
+      case kAddressKindWild:
+        return data.addr;
+      case kAddressKindShadow:
+        return data.shadow.addr;
+      case kAddressKindHeap:
+        return data.heap.addr;
+      case kAddressKindStack:
+        return data.stack.addr;
+      case kAddressKindGlobal:
+        return data.global.addr;
+    }
+    UNREACHABLE("AddressInformation kind is invalid");
+  }
+  void Print() const {
+    switch (data.kind) {
+      case kAddressKindWild:
+        Printf("Address %p is a wild pointer.\n", data.addr);
+        return;
+      case kAddressKindShadow:
+        return data.shadow.Print();
+      case kAddressKindHeap:
+        return data.heap.Print();
+      case kAddressKindStack:
+        return data.stack.Print();
+      case kAddressKindGlobal:
+        return data.global.Print();
+    }
+    UNREACHABLE("AddressInformation kind is invalid");
+  }
+
+  void StoreTo(AddressDescriptionData *dst) const { *dst = data; }
+
+  const ShadowAddressDescription *AsShadow() const {
+    return data.kind == kAddressKindShadow ? &data.shadow : nullptr;
+  }
+  const HeapAddressDescription *AsHeap() const {
+    return data.kind == kAddressKindHeap ? &data.heap : nullptr;
+  }
+  const StackAddressDescription *AsStack() const {
+    return data.kind == kAddressKindStack ? &data.stack : nullptr;
+  }
+  const GlobalAddressDescription *AsGlobal() const {
+    return data.kind == kAddressKindGlobal ? &data.global : nullptr;
+  }
+};
+
 }  // namespace __asan
 
 #endif  // ASAN_DESCRIPTIONS_H

Modified: compiler-rt/trunk/lib/asan/asan_report.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_report.h?rev=281090&r1=281089&r2=281090&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_report.h (original)
+++ compiler-rt/trunk/lib/asan/asan_report.h Fri Sep  9 15:43:20 2016
@@ -25,14 +25,6 @@ struct StackVarDescr {
   uptr name_len;
 };
 
-struct AddressDescription {
-  char *name;
-  uptr name_size;
-  uptr region_address;
-  uptr region_size;
-  const char *region_kind;
-};
-
 // Returns the number of globals close to the provided address and copies
 // them to "globals" array.
 int GetGlobalsForAddress(uptr addr, __asan_global *globals, u32 *reg_sites,




More information about the llvm-commits mailing list