[compiler-rt] DO_NOT_MERGE (PR #66682)

Vitaly Buka via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 19 23:51:14 PDT 2023


https://github.com/vitalybuka updated https://github.com/llvm/llvm-project/pull/66682

>From 03d8889dd852de5154eea58a6f3949b00cd2b2bd Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Tue, 19 Sep 2023 19:43:48 -0700
Subject: [PATCH 1/5] [NFC][hwasan] More consts in BaseReport (#66682)

---
 compiler-rt/lib/hwasan/hwasan_report.cpp | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/compiler-rt/lib/hwasan/hwasan_report.cpp b/compiler-rt/lib/hwasan/hwasan_report.cpp
index 442c5b736611dfb..61e717136ccdd6a 100644
--- a/compiler-rt/lib/hwasan/hwasan_report.cpp
+++ b/compiler-rt/lib/hwasan/hwasan_report.cpp
@@ -372,7 +372,7 @@ static void PrintTagsAroundAddr(tag_t *tag_ptr) {
       "description of short granule tags\n");
 }
 
-static uptr GetTopPc(StackTrace *stack) {
+static uptr GetTopPc(const StackTrace *stack) {
   return stack->size ? StackTrace::GetPreviousInstructionPc(stack->trace[0])
                      : 0;
 }
@@ -416,12 +416,12 @@ class BaseReport {
   void PrintAddressDescription() const;
   void PrintHeapOrGlobalCandidate() const;
 
-  ScopedReport scoped_report;
-  StackTrace *stack = nullptr;
-  uptr tagged_addr = 0;
-  uptr access_size = 0;
-  uptr untagged_addr = 0;
-  tag_t ptr_tag = 0;
+  const ScopedReport scoped_report;
+  const StackTrace *stack = nullptr;
+  const uptr tagged_addr = 0;
+  const uptr access_size = 0;
+  const uptr untagged_addr = 0;
+  const tag_t ptr_tag = 0;
 
   uptr stack_allocations_count = 0;
   SavedStackAllocations stack_allocations[16];
@@ -752,7 +752,7 @@ class TailOverwrittenReport : public BaseReport {
   ~TailOverwrittenReport();
 
  private:
-  uptr orig_size;
+  const uptr orig_size;
   const u8 *expected;
 };
 

>From 40ac72793accfdee3052567a5953bb3233e8539e Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Tue, 19 Sep 2023 20:01:43 -0700
Subject: [PATCH 2/5] [NFC][hwasan] Set more fields by value and make them
 const (#66682)

---
 compiler-rt/lib/hwasan/hwasan_report.cpp | 113 +++++++++++++----------
 1 file changed, 63 insertions(+), 50 deletions(-)

diff --git a/compiler-rt/lib/hwasan/hwasan_report.cpp b/compiler-rt/lib/hwasan/hwasan_report.cpp
index 61e717136ccdd6a..b7344317f649760 100644
--- a/compiler-rt/lib/hwasan/hwasan_report.cpp
+++ b/compiler-rt/lib/hwasan/hwasan_report.cpp
@@ -386,14 +386,10 @@ class BaseReport {
         tagged_addr(tagged_addr),
         access_size(access_size),
         untagged_addr(UntagAddr(tagged_addr)),
-        ptr_tag(GetTagFromPointer(tagged_addr)) {
-    if (MemIsShadow(untagged_addr))
-      return;
-
-    CopyHeapChunk();
-    CopyAllocations();
-    candidate = FindBufferOverflowCandidate();
-  }
+        ptr_tag(GetTagFromPointer(tagged_addr)),
+        heap(CopyHeapChunk()),
+        allocations(CopyAllocations()),
+        candidate(FindBufferOverflowCandidate()) {}
 
  protected:
   struct OverflowCandidate {
@@ -410,12 +406,35 @@ class BaseReport {
     } heap;
   };
 
-  void CopyHeapChunk();
-  void CopyAllocations();
+  struct HeapAllocation {
+    HeapAllocationRecord har = {};
+    uptr ring_index = 0;
+    uptr num_matching_addrs = 0;
+    uptr num_matching_addrs_4b = 0;
+    u32 free_thread_id = 0;
+  };
+
+  struct Allocations {
+    ArrayRef<SavedStackAllocations> stack;
+    ArrayRef<HeapAllocation> heap;
+  };
+
+  struct HeapChunk {
+    uptr begin = 0;
+    uptr size = 0;
+    bool from_small_heap = false;
+    bool is_allocated = false;
+  };
+
+  HeapChunk CopyHeapChunk() const;
+  Allocations CopyAllocations();
   OverflowCandidate FindBufferOverflowCandidate() const;
   void PrintAddressDescription() const;
   void PrintHeapOrGlobalCandidate() const;
 
+  SavedStackAllocations stack_allocations_storage[16];
+  HeapAllocation heap_allocations_storage[256];
+
   const ScopedReport scoped_report;
   const StackTrace *stack = nullptr;
   const uptr tagged_addr = 0;
@@ -423,53 +442,44 @@ class BaseReport {
   const uptr untagged_addr = 0;
   const tag_t ptr_tag = 0;
 
-  uptr stack_allocations_count = 0;
-  SavedStackAllocations stack_allocations[16];
-
-  struct {
-    uptr begin = 0;
-    uptr size = 0;
-    bool from_small_heap = false;
-    bool is_allocated = false;
-  } heap;
-
-  OverflowCandidate candidate;
-
-  uptr heap_allocations_count = 0;
-  struct {
-    HeapAllocationRecord har = {};
-    uptr ring_index = 0;
-    uptr num_matching_addrs = 0;
-    uptr num_matching_addrs_4b = 0;
-    u32 free_thread_id = 0;
-  } heap_allocations[256];
+  const HeapChunk heap;
+  const Allocations allocations;
+  const OverflowCandidate candidate;
 };
 
-void BaseReport::CopyHeapChunk() {
+BaseReport::HeapChunk BaseReport::CopyHeapChunk() const {
+  HeapChunk result = {};
+  if (MemIsShadow(untagged_addr))
+    return result;
   HwasanChunkView chunk = FindHeapChunkByAddress(untagged_addr);
-  heap.begin = chunk.Beg();
-  if (heap.begin) {
-    heap.size = chunk.ActualSize();
-    heap.from_small_heap = chunk.FromSmallHeap();
-    heap.is_allocated = chunk.IsAllocated();
+  result.begin = chunk.Beg();
+  if (result.begin) {
+    result.size = chunk.ActualSize();
+    result.from_small_heap = chunk.FromSmallHeap();
+    result.is_allocated = chunk.IsAllocated();
   }
+  return result;
 }
 
-void BaseReport::CopyAllocations() {
+BaseReport::Allocations BaseReport::CopyAllocations() {
+  if (MemIsShadow(untagged_addr))
+    return {};
+  uptr stack_allocations_count = 0;
+  uptr heap_allocations_count = 0;
   hwasanThreadList().VisitAllLiveThreads([&](Thread *t) {
-    if (stack_allocations_count < ARRAY_SIZE(stack_allocations) &&
+    if (stack_allocations_count < ARRAY_SIZE(stack_allocations_storage) &&
         t->AddrIsInStack(untagged_addr)) {
-      stack_allocations[stack_allocations_count++].CopyFrom(t);
+      stack_allocations_storage[stack_allocations_count++].CopyFrom(t);
     }
 
-    if (heap_allocations_count < ARRAY_SIZE(heap_allocations)) {
+    if (heap_allocations_count < ARRAY_SIZE(heap_allocations_storage)) {
       // Scan all threads' ring buffers to find if it's a heap-use-after-free.
       HeapAllocationRecord har;
       uptr ring_index, num_matching_addrs, num_matching_addrs_4b;
       if (FindHeapAllocation(t->heap_allocations(), tagged_addr, &har,
                              &ring_index, &num_matching_addrs,
                              &num_matching_addrs_4b)) {
-        auto &ha = heap_allocations[heap_allocations_count++];
+        auto &ha = heap_allocations_storage[heap_allocations_count++];
         ha.har = har;
         ha.ring_index = ring_index;
         ha.num_matching_addrs = num_matching_addrs;
@@ -478,9 +488,15 @@ void BaseReport::CopyAllocations() {
       }
     }
   });
+
+  return {{stack_allocations_storage, stack_allocations_count},
+          {heap_allocations_storage, heap_allocations_count}};
 }
 
 BaseReport::OverflowCandidate BaseReport::FindBufferOverflowCandidate() const {
+  OverflowCandidate result = {};
+  if (MemIsShadow(untagged_addr))
+    return result;
   // Check if this looks like a heap buffer overflow by scanning
   // the shadow left and right and looking for the first adjacent
   // object with a different memory tag. If that tag matches ptr_tag,
@@ -502,7 +518,6 @@ BaseReport::OverflowCandidate BaseReport::FindBufferOverflowCandidate() const {
     ++right;
   }
 
-  OverflowCandidate result = {};
   constexpr auto kCloseCandidateDistance = 1;
   result.is_close = candidate_distance <= kCloseCandidateDistance;
 
@@ -620,29 +635,27 @@ void BaseReport::PrintAddressDescription() const {
 
   // Check stack first. If the address is on the stack of a live thread, we
   // know it cannot be a heap / global overflow.
-  for (uptr i = 0; i < stack_allocations_count; ++i) {
-    const auto &allocations = stack_allocations[i];
+  for (const auto &sa : allocations.stack) {
     // TODO(fmayer): figure out how to distinguish use-after-return and
     // stack-buffer-overflow.
     Printf("%s", d.Error());
     Printf("\nCause: stack tag-mismatch\n");
     Printf("%s", d.Location());
     Printf("Address %p is located in stack of thread T%zd\n", untagged_addr,
-           allocations.thread_id());
+           sa.thread_id());
     Printf("%s", d.Default());
-    announce_by_id(allocations.thread_id());
-    PrintStackAllocations(allocations.get(), ptr_tag, untagged_addr);
+    announce_by_id(sa.thread_id());
+    PrintStackAllocations(sa.get(), ptr_tag, untagged_addr);
     num_descriptions_printed++;
   }
 
-  if (!stack_allocations_count && candidate.untagged_addr &&
+  if (allocations.stack.empty() && candidate.untagged_addr &&
       candidate.is_close) {
     PrintHeapOrGlobalCandidate();
     num_descriptions_printed++;
   }
 
-  for (uptr i = 0; i < heap_allocations_count; ++i) {
-    const auto &ha = heap_allocations[i];
+  for (const auto &ha : allocations.heap) {
     const HeapAllocationRecord har = ha.har;
 
     Printf("%s", d.Error());

>From 29e4f2bf21185e052625d81d1293cdd2c56a99af Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Mon, 18 Sep 2023 19:17:02 -0700
Subject: [PATCH 3/5] [NFC][hwasan] Use stored chunk in TailOverwrittenReport
 (#66682)

---
 compiler-rt/lib/hwasan/hwasan_report.cpp | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/compiler-rt/lib/hwasan/hwasan_report.cpp b/compiler-rt/lib/hwasan/hwasan_report.cpp
index b7344317f649760..5e425fccf4cfba5 100644
--- a/compiler-rt/lib/hwasan/hwasan_report.cpp
+++ b/compiler-rt/lib/hwasan/hwasan_report.cpp
@@ -422,6 +422,7 @@ class BaseReport {
   struct HeapChunk {
     uptr begin = 0;
     uptr size = 0;
+    u32 stack_id = 0;
     bool from_small_heap = false;
     bool is_allocated = false;
   };
@@ -457,6 +458,7 @@ BaseReport::HeapChunk BaseReport::CopyHeapChunk() const {
     result.size = chunk.ActualSize();
     result.from_small_heap = chunk.FromSmallHeap();
     result.is_allocated = chunk.IsAllocated();
+    result.stack_id = chunk.GetAllocStackId();
   }
   return result;
 }
@@ -792,12 +794,11 @@ TailOverwrittenReport::~TailOverwrittenReport() {
   Printf("deallocated here:\n");
   Printf("%s", d.Default());
   stack->Print();
-  HwasanChunkView chunk = FindHeapChunkByAddress(untagged_addr);
-  if (chunk.Beg()) {
+  if (heap.begin) {
     Printf("%s", d.Allocation());
     Printf("allocated here:\n");
     Printf("%s", d.Default());
-    GetStackTraceFromId(chunk.GetAllocStackId()).Print();
+    GetStackTraceFromId(heap.stack_id).Print();
   }
 
   InternalScopedString s;

>From bfee0f767efbde09553ee0a910077d0eb4d19825 Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Mon, 18 Sep 2023 19:29:57 -0700
Subject: [PATCH 4/5] [NFC][hwasan] Stored tail early (#66682)

---
 compiler-rt/lib/hwasan/hwasan_report.cpp | 32 +++++++++++++-----------
 1 file changed, 17 insertions(+), 15 deletions(-)

diff --git a/compiler-rt/lib/hwasan/hwasan_report.cpp b/compiler-rt/lib/hwasan/hwasan_report.cpp
index 5e425fccf4cfba5..f7dfe611adea380 100644
--- a/compiler-rt/lib/hwasan/hwasan_report.cpp
+++ b/compiler-rt/lib/hwasan/hwasan_report.cpp
@@ -763,24 +763,28 @@ class TailOverwrittenReport : public BaseReport {
                                  uptr orig_size, const u8 *expected)
       : BaseReport(stack, flags()->halt_on_error, tagged_addr, 0),
         orig_size(orig_size),
-        expected(expected) {}
+        tail_size(kShadowAlignment - (orig_size % kShadowAlignment)) {
+    CHECK_GT(tail_size, 0U);
+    CHECK_LT(tail_size, kShadowAlignment);
+    internal_memcpy(tail_copy,
+                    reinterpret_cast<u8 *>(untagged_addr + orig_size),
+                    tail_size);
+    internal_memcpy(actual_expected, expected, tail_size);
+    // Short granule is stashed in the last byte of the magic string. To avoid
+    // confusion, make the expected magic string contain the short granule tag.
+    if (orig_size % kShadowAlignment != 0)
+      actual_expected[tail_size - 1] = ptr_tag;
+  }
   ~TailOverwrittenReport();
 
  private:
-  const uptr orig_size;
-  const u8 *expected;
+  const uptr orig_size = 0;
+  const uptr tail_size = 0;
+  u8 actual_expected[kShadowAlignment] = {};
+  u8 tail_copy[kShadowAlignment] = {};
 };
 
 TailOverwrittenReport::~TailOverwrittenReport() {
-  uptr tail_size = kShadowAlignment - (orig_size % kShadowAlignment);
-  u8 actual_expected[kShadowAlignment];
-  internal_memcpy(actual_expected, expected, tail_size);
-  // Short granule is stashed in the last byte of the magic string. To avoid
-  // confusion, make the expected magic string contain the short granule tag.
-  if (orig_size % kShadowAlignment != 0) {
-    actual_expected[tail_size - 1] = ptr_tag;
-  }
-
   Decorator d;
   Printf("%s", d.Error());
   const char *bug_type = "allocation-tail-overwritten";
@@ -802,9 +806,7 @@ TailOverwrittenReport::~TailOverwrittenReport() {
   }
 
   InternalScopedString s;
-  CHECK_GT(tail_size, 0U);
-  CHECK_LT(tail_size, kShadowAlignment);
-  u8 *tail = reinterpret_cast<u8*>(untagged_addr + orig_size);
+  u8 *tail = tail_copy;
   s.AppendF("Tail contains: ");
   for (uptr i = 0; i < kShadowAlignment - tail_size; i++) s.AppendF(".. ");
   for (uptr i = 0; i < tail_size; i++) s.AppendF("%02x ", tail[i]);

>From 61289c01fa2972bb842c08706316e9fa1c898041 Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Tue, 19 Sep 2023 18:54:06 -0700
Subject: [PATCH 5/5] [NFC][hwasan] Stored shadow bytes early (#66682)

---
 compiler-rt/lib/hwasan/hwasan_report.cpp | 146 +++++++++++++++--------
 1 file changed, 99 insertions(+), 47 deletions(-)

diff --git a/compiler-rt/lib/hwasan/hwasan_report.cpp b/compiler-rt/lib/hwasan/hwasan_report.cpp
index f7dfe611adea380..28e0610239772a3 100644
--- a/compiler-rt/lib/hwasan/hwasan_report.cpp
+++ b/compiler-rt/lib/hwasan/hwasan_report.cpp
@@ -25,6 +25,7 @@
 #include "sanitizer_common/sanitizer_array_ref.h"
 #include "sanitizer_common/sanitizer_common.h"
 #include "sanitizer_common/sanitizer_flags.h"
+#include "sanitizer_common/sanitizer_internal_defs.h"
 #include "sanitizer_common/sanitizer_mutex.h"
 #include "sanitizer_common/sanitizer_report_decorator.h"
 #include "sanitizer_common/sanitizer_stackdepot.h"
@@ -321,55 +322,61 @@ static uptr GetGlobalSizeFromDescriptor(uptr ptr) {
 
 void ReportStats() {}
 
-static void PrintTagInfoAroundAddr(tag_t *tag_ptr, uptr num_rows,
-                                   void (*print_tag)(InternalScopedString &s,
-                                                     tag_t *tag)) {
+template <typename PrintTag>
+static void PrintTagInfoAroundAddr(uptr addr, uptr num_rows,
+                                   InternalScopedString &s,
+                                   PrintTag print_tag) {
   const uptr row_len = 16;  // better be power of two.
-  tag_t *center_row_beg = reinterpret_cast<tag_t *>(
-      RoundDownTo(reinterpret_cast<uptr>(tag_ptr), row_len));
-  tag_t *beg_row = center_row_beg - row_len * (num_rows / 2);
-  tag_t *end_row = center_row_beg + row_len * ((num_rows + 1) / 2);
-  InternalScopedString s;
-  for (tag_t *row = beg_row; row < end_row; row += row_len) {
+  uptr center_row_beg = RoundDownTo(addr, row_len);
+  uptr beg_row = center_row_beg - row_len * (num_rows / 2);
+  uptr end_row = center_row_beg + row_len * ((num_rows + 1) / 2);
+  for (uptr row = beg_row; row < end_row; row += row_len) {
     s.Append(row == center_row_beg ? "=>" : "  ");
-    s.AppendF("%p:", (void *)ShadowToMem(reinterpret_cast<uptr>(row)));
+    s.AppendF("%p:", (void *)ShadowToMem(row));
     for (uptr i = 0; i < row_len; i++) {
-      s.Append(row + i == tag_ptr ? "[" : " ");
-      print_tag(s, &row[i]);
-      s.Append(row + i == tag_ptr ? "]" : " ");
+      s.Append(row + i == addr ? "[" : " ");
+      print_tag(s, row + i);
+      s.Append(row + i == addr ? "]" : " ");
     }
     s.AppendF("\n");
   }
-  Printf("%s", s.data());
 }
 
-static void PrintTagsAroundAddr(tag_t *tag_ptr) {
-  Printf(
+template <typename GetTag, typename GetShortTag>
+static void PrintTagsAroundAddr(uptr addr, GetTag get_tag,
+                                GetShortTag get_short_tag) {
+  InternalScopedString s;
+  addr = MemToShadow(addr);
+  s.AppendF(
       "Memory tags around the buggy address (one tag corresponds to %zd "
       "bytes):\n",
       kShadowAlignment);
-  PrintTagInfoAroundAddr(tag_ptr, 17, [](InternalScopedString &s, tag_t *tag) {
-    s.AppendF("%02x", *tag);
-  });
+  PrintTagInfoAroundAddr(addr, 17, s,
+                         [&](InternalScopedString &s, uptr tag_addr) {
+                           tag_t tag = get_tag(tag_addr);
+                           s.AppendF("%02x", tag);
+                         });
 
-  Printf(
+  s.AppendF(
       "Tags for short granules around the buggy address (one tag corresponds "
       "to %zd bytes):\n",
       kShadowAlignment);
-  PrintTagInfoAroundAddr(tag_ptr, 3, [](InternalScopedString &s, tag_t *tag) {
-    if (*tag >= 1 && *tag <= kShadowAlignment) {
-      uptr granule_addr = ShadowToMem(reinterpret_cast<uptr>(tag));
-      s.AppendF("%02x",
-                *reinterpret_cast<u8 *>(granule_addr + kShadowAlignment - 1));
-    } else {
-      s.AppendF("..");
-    }
-  });
-  Printf(
+  PrintTagInfoAroundAddr(addr, 3, s,
+                         [&](InternalScopedString &s, uptr tag_addr) {
+                           tag_t tag = get_tag(tag_addr);
+                           if (tag >= 1 && tag <= kShadowAlignment) {
+                             tag_t short_tag = get_short_tag(tag_addr);
+                             s.AppendF("%02x", short_tag);
+                           } else {
+                             s.AppendF("..");
+                           }
+                         });
+  s.AppendF(
       "See "
       "https://clang.llvm.org/docs/"
       "HardwareAssistedAddressSanitizerDesign.html#short-granules for a "
       "description of short granule tags\n");
+  Printf("%s", s.data());
 }
 
 static uptr GetTopPc(const StackTrace *stack) {
@@ -389,7 +396,9 @@ class BaseReport {
         ptr_tag(GetTagFromPointer(tagged_addr)),
         heap(CopyHeapChunk()),
         allocations(CopyAllocations()),
-        candidate(FindBufferOverflowCandidate()) {}
+        candidate(FindBufferOverflowCandidate()) {
+    CopyShadow();
+  }
 
  protected:
   struct OverflowCandidate {
@@ -427,6 +436,9 @@ class BaseReport {
     bool is_allocated = false;
   };
 
+  void CopyShadow();
+  tag_t GetTagCopy(uptr addr) const;
+  tag_t GetShortTagCopy(uptr addr) const;
   HeapChunk CopyHeapChunk() const;
   Allocations CopyAllocations();
   OverflowCandidate FindBufferOverflowCandidate() const;
@@ -446,8 +458,51 @@ class BaseReport {
   const HeapChunk heap;
   const Allocations allocations;
   const OverflowCandidate candidate;
+
+  struct {
+    uptr addr = 0;
+    tag_t tags[512] = {};
+    tag_t short_tags[ARRAY_SIZE(tags)] = {};
+  } shadow;
 };
 
+void BaseReport::CopyShadow() {
+  if (!MemIsApp(untagged_addr))
+    return;
+
+  shadow.addr = MemToShadow(untagged_addr) - ARRAY_SIZE(shadow.tags) / 2;
+  for (uptr i = 0; i < ARRAY_SIZE(shadow.tags); ++i) {
+    uptr tag_addr = shadow.addr + i;
+    if (!MemIsShadow(tag_addr))
+      continue;
+    shadow.tags[i] = *reinterpret_cast<tag_t *>(tag_addr);
+    uptr granule_addr = ShadowToMem(tag_addr);
+    if (1 <= shadow.tags[i] && shadow.tags[i] <= kShadowAlignment &&
+        IsAccessibleMemoryRange(granule_addr, kShadowAlignment)) {
+      shadow.short_tags[i] =
+          *reinterpret_cast<tag_t *>(granule_addr + kShadowAlignment - 1);
+    }
+  }
+}
+
+tag_t BaseReport::GetTagCopy(uptr addr) const {
+  if (addr < shadow.addr)
+    return 0;
+  uptr idx = addr - shadow.addr;
+  if (idx >= ARRAY_SIZE(shadow.tags))
+    return 0;
+  return shadow.tags[idx];
+}
+
+tag_t BaseReport::GetShortTagCopy(uptr addr) const {
+  if (addr < shadow.addr)
+    return 0;
+  uptr idx = addr - shadow.addr;
+  if (idx >= ARRAY_SIZE(shadow.short_tags))
+    return 0;
+  return shadow.short_tags[idx];
+}
+
 BaseReport::HeapChunk BaseReport::CopyHeapChunk() const {
   HeapChunk result = {};
   if (MemIsShadow(untagged_addr))
@@ -720,15 +775,6 @@ class InvalidFreeReport : public BaseReport {
 };
 
 InvalidFreeReport::~InvalidFreeReport() {
-  tag_t *tag_ptr = nullptr;
-  tag_t mem_tag = 0;
-  if (MemIsApp(untagged_addr)) {
-    tag_ptr = reinterpret_cast<tag_t *>(MemToShadow(untagged_addr));
-    if (MemIsShadow(reinterpret_cast<uptr>(tag_ptr)))
-      mem_tag = *tag_ptr;
-    else
-      tag_ptr = nullptr;
-  }
   Decorator d;
   Printf("%s", d.Error());
   uptr pc = GetTopPc(stack);
@@ -742,16 +788,19 @@ InvalidFreeReport::~InvalidFreeReport() {
            SanitizerToolName, bug_type, untagged_addr, pc);
   }
   Printf("%s", d.Access());
-  if (tag_ptr)
-    Printf("tags: %02x/%02x (ptr/mem)\n", ptr_tag, mem_tag);
+  if (shadow.addr)
+    Printf("tags: %02x/%02x (ptr/mem)\n", ptr_tag, GetTagCopy(untagged_addr));
   Printf("%s", d.Default());
 
   stack->Print();
 
   PrintAddressDescription();
 
-  if (tag_ptr)
-    PrintTagsAroundAddr(tag_ptr);
+  if (shadow.addr) {
+    PrintTagsAroundAddr(
+        untagged_addr, [&](uptr addr) { return GetTagCopy(addr); },
+        [&](uptr addr) { return GetShortTagCopy(addr); });
+  }
 
   MaybePrintAndroidHelpUrl();
   ReportErrorSummary(bug_type, stack);
@@ -833,8 +882,9 @@ TailOverwrittenReport::~TailOverwrittenReport() {
   Printf("%s", s.data());
   GetCurrentThread()->Announce();
 
-  tag_t *tag_ptr = reinterpret_cast<tag_t*>(MemToShadow(untagged_addr));
-  PrintTagsAroundAddr(tag_ptr);
+  PrintTagsAroundAddr(
+      untagged_addr, [&](uptr addr) { return GetTagCopy(addr); },
+      [&](uptr addr) { return GetShortTagCopy(addr); });
 
   MaybePrintAndroidHelpUrl();
   ReportErrorSummary(bug_type, stack);
@@ -911,7 +961,9 @@ TagMismatchReport::~TagMismatchReport() {
   PrintAddressDescription();
   t->Announce();
 
-  PrintTagsAroundAddr(tag_ptr);
+  PrintTagsAroundAddr(
+      untagged_addr + offset, [&](uptr addr) { return GetTagCopy(addr); },
+      [&](uptr addr) { return GetShortTagCopy(addr); });
 
   if (registers_frame)
     ReportRegisters(registers_frame, pc);



More information about the llvm-commits mailing list