From 3614218ce8485a6dd89edc38369fe0029549f559 Mon Sep 17 00:00:00 2001 From: Vitaly Buka Date: Thu, 21 Sep 2023 13:27:43 -0700 Subject: [PATCH] [hwasan] Optimize shadow shapshot size Now we copy only tags we will print. CHECKs in GetTagCopy and GetShortTagCopy ensure that. --- compiler-rt/lib/hwasan/hwasan_report.cpp | 51 +++++++++++++++++------- 1 file changed, 36 insertions(+), 15 deletions(-) diff --git a/compiler-rt/lib/hwasan/hwasan_report.cpp b/compiler-rt/lib/hwasan/hwasan_report.cpp index f74e26af70a0f..d499f97328893 100644 --- a/compiler-rt/lib/hwasan/hwasan_report.cpp +++ b/compiler-rt/lib/hwasan/hwasan_report.cpp @@ -323,6 +323,21 @@ static uptr GetGlobalSizeFromDescriptor(uptr ptr) { void ReportStats() {} +constexpr uptr kDumpWidth = 16; +constexpr uptr kShadowLines = 17; +constexpr uptr kShadowDumpSize = kShadowLines * kDumpWidth; + +constexpr uptr kShortLines = 3; +constexpr uptr kShortDumpSize = kShortLines * kDumpWidth; +constexpr uptr kShortDumpOffset = (kShadowLines - kShortLines) / 2 * kDumpWidth; + +static uptr GetPrintTagStart(uptr addr) { + addr = MemToShadow(addr); + addr = RoundDownTo(addr, kDumpWidth); + addr -= kDumpWidth * (kShadowLines / 2); + return addr; +} + template static void PrintTagInfoAroundAddr(uptr addr, uptr num_rows, InternalScopedString &s, @@ -352,7 +367,7 @@ static void PrintTagsAroundAddr(uptr addr, GetTag get_tag, "Memory tags around the buggy address (one tag corresponds to %zd " "bytes):\n", kShadowAlignment); - PrintTagInfoAroundAddr(addr, 17, s, + PrintTagInfoAroundAddr(addr, kShadowLines, s, [&](InternalScopedString &s, uptr tag_addr) { tag_t tag = get_tag(tag_addr); s.AppendF("%02x", tag); @@ -362,7 +377,7 @@ static void PrintTagsAroundAddr(uptr addr, GetTag get_tag, "Tags for short granules around the buggy address (one tag corresponds " "to %zd bytes):\n", kShadowAlignment); - PrintTagInfoAroundAddr(addr, 3, s, + PrintTagInfoAroundAddr(addr, kShortLines, s, [&](InternalScopedString &s, uptr tag_addr) { tag_t tag = get_tag(tag_addr); if (tag >= 1 && tag <= kShadowAlignment) { @@ -439,8 +454,8 @@ class BaseReport { struct Shadow { uptr addr = 0; - tag_t tags[512] = {}; - tag_t short_tags[ARRAY_SIZE(tags)] = {}; + tag_t tags[kShadowDumpSize] = {}; + tag_t short_tags[kShortDumpSize] = {}; }; sptr FindMismatchOffset() const; @@ -508,18 +523,24 @@ BaseReport::Shadow BaseReport::CopyShadow() const { if (!MemIsApp(untagged_addr)) return result; - result.addr = MemToShadow(untagged_addr) - ARRAY_SIZE(result.tags) / 2; - for (uptr i = 0; i < ARRAY_SIZE(result.tags); ++i) { - uptr tag_addr = result.addr + i; - if (!MemIsShadow(tag_addr)) - continue; - result.tags[i] = *reinterpret_cast(tag_addr); - uptr granule_addr = ShadowToMem(tag_addr); - if (1 <= result.tags[i] && result.tags[i] <= kShadowAlignment && + result.addr = GetPrintTagStart(untagged_addr + mismatch_offset); + uptr tag_addr = result.addr; + for (tag_t &tag_copy : result.tags) { + if (MemIsShadow(tag_addr)) + tag_copy = *reinterpret_cast(tag_addr); + ++tag_addr; + } + + uptr short_tags_addr = result.addr + kShortDumpOffset; + for (tag_t &tag_copy : result.short_tags) { + tag_t tag = GetTagCopy(short_tags_addr); + uptr granule_addr = ShadowToMem(short_tags_addr); + if (1 <= tag && tag <= kShadowAlignment && IsAccessibleMemoryRange(granule_addr, kShadowAlignment)) { - result.short_tags[i] = + tag_copy = *reinterpret_cast(granule_addr + kShadowAlignment - 1); } + ++short_tags_addr; } return result; } @@ -532,8 +553,8 @@ tag_t BaseReport::GetTagCopy(uptr addr) const { } tag_t BaseReport::GetShortTagCopy(uptr addr) const { - CHECK_GE(addr, shadow.addr); - uptr idx = addr - shadow.addr; + CHECK_GE(addr, shadow.addr + kShortDumpOffset); + uptr idx = addr - shadow.addr - kShortDumpOffset; CHECK_LT(idx, ARRAY_SIZE(shadow.short_tags)); return shadow.short_tags[idx]; }