[compiler-rt] [TSan] Clarify and enforce shadow end alignment (PR #144648)

Kunqiu Chen via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 25 00:29:13 PDT 2025


https://github.com/Camsyn updated https://github.com/llvm/llvm-project/pull/144648

>From cfe2a93c5dea170829844969201f6cbfc7e89656 Mon Sep 17 00:00:00 2001
From: Camsyn <camsyn at foxmail.com>
Date: Tue, 17 Jun 2025 15:33:15 +0800
Subject: [PATCH 1/6] [TSan] Fix potentially problematic shadow end
 calculations

This is an improvement that enhances the robustness of the code.

Previously, the correct calculation of exclusive EndShadow relied on the
assumption that `addr_end % kShadowCell == 0`; however, in many current
usages, this assumption was not strictly guaranteed (although it did in
fact meet).

In addition, computing EndShadow does not require the corresponding
address to be AppMem; for example, HighAppEnd is not AppMem, but can
still be used to calculate EndShadow.

For example, for the AppMem range [0, 1), `s = MemToShadow(0)` is equal
to `MemToShadow(1)`. The previous logic would incorrectly deduce an
empty shadow range [s, s) while the correct shadow range should be
[s, s + kShadowSize * kShadowCnt) to cover all the related shadow memory
for the accessed cell.

This commit addresses this in two ways:
1. It introduces a dedicated utility function, i.e., `MemToEndShadow`,
    to correctly calculate the end of a shadow memory range, accounting
    for the memory cell granularity.
2. It replaces existing (and potentially incorrect) calculations of the
    shadow end with this new utility function.

Additionally, the previous commit 4052de6 resolved a problem with
overestimating the shadow end; it did not consider `kShadowCell` and
could therefore lead to underestimates. This is also corrected by
utilizing the `MemToEndShadow` function.
---
 .../lib/tsan/rtl/tsan_interface_java.cpp       |  3 +--
 compiler-rt/lib/tsan/rtl/tsan_platform.h       | 18 ++++++++++++++++++
 .../lib/tsan/rtl/tsan_platform_linux.cpp       |  2 +-
 compiler-rt/lib/tsan/rtl/tsan_rtl.cpp          |  6 +++---
 compiler-rt/lib/tsan/rtl/tsan_rtl_access.cpp   |  9 ++++-----
 5 files changed, 27 insertions(+), 11 deletions(-)

diff --git a/compiler-rt/lib/tsan/rtl/tsan_interface_java.cpp b/compiler-rt/lib/tsan/rtl/tsan_interface_java.cpp
index 7c15a16388268..3e324eef9cb8d 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_interface_java.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_interface_java.cpp
@@ -122,7 +122,6 @@ void __tsan_java_move(jptr src, jptr dst, jptr size) {
   DCHECK_GE(dst, jctx->heap_begin);
   DCHECK_LE(dst + size, jctx->heap_begin + jctx->heap_size);
   DCHECK_NE(dst, src);
-  DCHECK_NE(size, 0);
 
   // Assuming it's not running concurrently with threads that do
   // memory accesses and mutex operations (stop-the-world phase).
@@ -132,7 +131,7 @@ void __tsan_java_move(jptr src, jptr dst, jptr size) {
   // We used to move shadow from src to dst, but the trace format does not
   // support that anymore as it contains addresses of accesses.
   RawShadow *d = MemToShadow(dst);
-  RawShadow *dend = MemToShadow(dst + size);
+  RawShadow *dend = MemToEndShadow(dst + size);
   ShadowSet(d, dend, Shadow::kEmpty);
 }
 
diff --git a/compiler-rt/lib/tsan/rtl/tsan_platform.h b/compiler-rt/lib/tsan/rtl/tsan_platform.h
index ada594bc11fc7..99e131a1807f8 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_platform.h
+++ b/compiler-rt/lib/tsan/rtl/tsan_platform.h
@@ -968,6 +968,24 @@ RawShadow *MemToShadow(uptr x) {
   return reinterpret_cast<RawShadow *>(SelectMapping<MemToShadowImpl>(x));
 }
 
+struct MemToEndShadowImpl {
+  template <typename Mapping>
+  static uptr Apply(uptr x) {
+    return (((x + kShadowCell - 1) &
+             ~(Mapping::kShadowMsk | (kShadowCell - 1))) ^
+            Mapping::kShadowXor) *
+               kShadowMultiplier +
+           Mapping::kShadowAdd;
+  }
+};
+
+// If addr % kShadowCell == 0, then MemToEndShadow(addr) == MemToShadow(addr)
+// Otherwise, MemToEndShadow(addr) == MemToShadow(addr) + kShadowCnt
+ALWAYS_INLINE
+RawShadow *MemToEndShadow(uptr x) {
+  return reinterpret_cast<RawShadow *>(SelectMapping<MemToEndShadowImpl>(x));
+}
+
 struct MemToMetaImpl {
   template <typename Mapping>
   static u32 *Apply(uptr x) {
diff --git a/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp b/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp
index 2c55645a15479..dbf583b362359 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp
@@ -195,7 +195,7 @@ static NOINLINE void MapRodata(char* buffer, uptr size) {
         !segment.IsWritable() && IsAppMem(segment.start)) {
       // Assume it's .rodata
       char *shadow_start = (char *)MemToShadow(segment.start);
-      char *shadow_end = (char *)MemToShadow(segment.end);
+      char *shadow_end = (char *)MemToEndShadow(segment.end);
       for (char *p = shadow_start; p < shadow_end;
            p += marker.size() * sizeof(RawShadow)) {
         internal_mmap(
diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp b/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp
index 981f37b89e784..05a2d22b6889d 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp
@@ -532,7 +532,7 @@ static void StopBackgroundThread() {
 
 void DontNeedShadowFor(uptr addr, uptr size) {
   ReleaseMemoryPagesToOS(reinterpret_cast<uptr>(MemToShadow(addr)),
-                         reinterpret_cast<uptr>(MemToShadow(addr + size)));
+                         reinterpret_cast<uptr>(MemToEndShadow(addr + size)));
 }
 
 #if !SANITIZER_GO
@@ -588,12 +588,12 @@ void MapShadow(uptr addr, uptr size) {
   // CHECK_EQ(addr, addr & ~((64 << 10) - 1));  // windows wants 64K alignment
   const uptr kPageSize = GetPageSizeCached();
   uptr shadow_begin = RoundDownTo((uptr)MemToShadow(addr), kPageSize);
-  uptr shadow_end = RoundUpTo((uptr)MemToShadow(addr + size), kPageSize);
+  uptr shadow_end = RoundUpTo((uptr)MemToEndShadow(addr + size), kPageSize);
   if (!MmapFixedNoReserve(shadow_begin, shadow_end - shadow_begin, "shadow"))
     Die();
 #else
   uptr shadow_begin = RoundDownTo((uptr)MemToShadow(addr), (64 << 10));
-  uptr shadow_end = RoundUpTo((uptr)MemToShadow(addr + size), (64 << 10));
+  uptr shadow_end = RoundUpTo((uptr)MemToEndShadow(addr + size), (64 << 10));
   VPrintf(2, "MapShadow for (0x%zx-0x%zx), begin/end: (0x%zx-0x%zx)\n",
           addr, addr + size, shadow_begin, shadow_end);
 
diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl_access.cpp b/compiler-rt/lib/tsan/rtl/tsan_rtl_access.cpp
index bd8deefefa1bc..e329cee9751e5 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_rtl_access.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_rtl_access.cpp
@@ -688,16 +688,15 @@ void MemoryAccessRangeT(ThreadState* thr, uptr pc, uptr addr, uptr size) {
     DCHECK(IsShadowMem(shadow_mem));
   }
 
-  RawShadow* shadow_mem_end = reinterpret_cast<RawShadow*>(
-      reinterpret_cast<uptr>(shadow_mem) + size * kShadowMultiplier - 1);
-  if (!IsShadowMem(shadow_mem_end)) {
-    Printf("Bad shadow end addr: %p (%p)\n", shadow_mem_end,
+  RawShadow* shadow_mem_end = MemToEndShadow(addr + size);
+  if (size > 0 && !IsShadowMem(shadow_mem_end - 1)) {
+    Printf("Bad shadow end addr: %p (%p)\n", shadow_mem_end - 1,
            (void*)(addr + size - 1));
     Printf(
         "Shadow start addr (ok): %p (%p); size: 0x%zx; kShadowMultiplier: "
         "%zx\n",
         shadow_mem, (void*)addr, size, kShadowMultiplier);
-    DCHECK(IsShadowMem(shadow_mem_end));
+    DCHECK(IsShadowMem(shadow_mem_end - 1));
   }
 #endif
 

>From 71da1d836332917dd39039a487e346dcdf383eab Mon Sep 17 00:00:00 2001
From: Camsyn <camsyn at foxmail.com>
Date: Sat, 21 Jun 2025 15:53:43 +0800
Subject: [PATCH 2/6] Remove XFAIL marker from 2 tests

---
 compiler-rt/test/tsan/java_heap_init2.cpp   | 1 -
 compiler-rt/test/tsan/munmap_clear_shadow.c | 1 -
 2 files changed, 2 deletions(-)

diff --git a/compiler-rt/test/tsan/java_heap_init2.cpp b/compiler-rt/test/tsan/java_heap_init2.cpp
index 2e5724d930e8f..3317a5b3c2f43 100644
--- a/compiler-rt/test/tsan/java_heap_init2.cpp
+++ b/compiler-rt/test/tsan/java_heap_init2.cpp
@@ -1,5 +1,4 @@
 // RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
-// XFAIL: *
 
 #include "java.h"
 #include <errno.h>
diff --git a/compiler-rt/test/tsan/munmap_clear_shadow.c b/compiler-rt/test/tsan/munmap_clear_shadow.c
index 8a435a84258f5..f48a12a4cc0cb 100644
--- a/compiler-rt/test/tsan/munmap_clear_shadow.c
+++ b/compiler-rt/test/tsan/munmap_clear_shadow.c
@@ -1,5 +1,4 @@
 // RUN: %clang_tsan %s -o %t && %run %t | FileCheck %s
-// XFAIL: *
 
 #include "test.h"
 #include <assert.h>

>From eedddb99bfbf56edf68e6045d1996079b4df5c76 Mon Sep 17 00:00:00 2001
From: Camsyn <camsyn at foxmail.com>
Date: Sat, 21 Jun 2025 20:45:42 +0800
Subject: [PATCH 3/6] Use RoundUp on demand instead of a new util function

We don't always need to get the real shadow end, for example, some
shadow clear, if using the real shadow end, it will cause overcleaning
(i.e., clear [0, 1) makes [1, 8) inaccessible when kShadowCell == 8).

So when we do need to get the real end, use RoundUp in place.
For example, `unmap(addr, sz)` makes `[addr + sz, addr + PageSize)`
inaccessible, so we can safely clean up the full shadow (by getting
the real shadow end).
---
 .../lib/tsan/rtl/tsan_interface_java.cpp       |  2 +-
 compiler-rt/lib/tsan/rtl/tsan_platform.h       | 18 ------------------
 .../lib/tsan/rtl/tsan_platform_linux.cpp       |  2 +-
 compiler-rt/lib/tsan/rtl/tsan_rtl.cpp          | 13 +++++++++----
 compiler-rt/lib/tsan/rtl/tsan_rtl_access.cpp   |  6 ++++--
 5 files changed, 15 insertions(+), 26 deletions(-)

diff --git a/compiler-rt/lib/tsan/rtl/tsan_interface_java.cpp b/compiler-rt/lib/tsan/rtl/tsan_interface_java.cpp
index 3e324eef9cb8d..cb4d767d903d3 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_interface_java.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_interface_java.cpp
@@ -131,7 +131,7 @@ void __tsan_java_move(jptr src, jptr dst, jptr size) {
   // We used to move shadow from src to dst, but the trace format does not
   // support that anymore as it contains addresses of accesses.
   RawShadow *d = MemToShadow(dst);
-  RawShadow *dend = MemToEndShadow(dst + size);
+  RawShadow *dend = MemToShadow(dst + size);
   ShadowSet(d, dend, Shadow::kEmpty);
 }
 
diff --git a/compiler-rt/lib/tsan/rtl/tsan_platform.h b/compiler-rt/lib/tsan/rtl/tsan_platform.h
index 99e131a1807f8..ada594bc11fc7 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_platform.h
+++ b/compiler-rt/lib/tsan/rtl/tsan_platform.h
@@ -968,24 +968,6 @@ RawShadow *MemToShadow(uptr x) {
   return reinterpret_cast<RawShadow *>(SelectMapping<MemToShadowImpl>(x));
 }
 
-struct MemToEndShadowImpl {
-  template <typename Mapping>
-  static uptr Apply(uptr x) {
-    return (((x + kShadowCell - 1) &
-             ~(Mapping::kShadowMsk | (kShadowCell - 1))) ^
-            Mapping::kShadowXor) *
-               kShadowMultiplier +
-           Mapping::kShadowAdd;
-  }
-};
-
-// If addr % kShadowCell == 0, then MemToEndShadow(addr) == MemToShadow(addr)
-// Otherwise, MemToEndShadow(addr) == MemToShadow(addr) + kShadowCnt
-ALWAYS_INLINE
-RawShadow *MemToEndShadow(uptr x) {
-  return reinterpret_cast<RawShadow *>(SelectMapping<MemToEndShadowImpl>(x));
-}
-
 struct MemToMetaImpl {
   template <typename Mapping>
   static u32 *Apply(uptr x) {
diff --git a/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp b/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp
index dbf583b362359..2c55645a15479 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp
@@ -195,7 +195,7 @@ static NOINLINE void MapRodata(char* buffer, uptr size) {
         !segment.IsWritable() && IsAppMem(segment.start)) {
       // Assume it's .rodata
       char *shadow_start = (char *)MemToShadow(segment.start);
-      char *shadow_end = (char *)MemToEndShadow(segment.end);
+      char *shadow_end = (char *)MemToShadow(segment.end);
       for (char *p = shadow_start; p < shadow_end;
            p += marker.size() * sizeof(RawShadow)) {
         internal_mmap(
diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp b/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp
index 05a2d22b6889d..f2b60e7e24cb3 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp
@@ -532,7 +532,7 @@ static void StopBackgroundThread() {
 
 void DontNeedShadowFor(uptr addr, uptr size) {
   ReleaseMemoryPagesToOS(reinterpret_cast<uptr>(MemToShadow(addr)),
-                         reinterpret_cast<uptr>(MemToEndShadow(addr + size)));
+                         reinterpret_cast<uptr>(MemToShadow(addr + size)));
 }
 
 #if !SANITIZER_GO
@@ -566,13 +566,18 @@ static bool IsValidMmapRange(uptr addr, uptr size) {
   return false;
 }
 
-void UnmapShadow(ThreadState *thr, uptr addr, uptr size) {
+void UnmapShadow(ThreadState* thr, uptr addr, uptr size) {
   if (size == 0 || !IsValidMmapRange(addr, size))
     return;
-  DontNeedShadowFor(addr, size);
+  // unmap shadow is related to semantic of mmap/munmap, so we
+  // should clear the whole shadow range, including the tail shadow
+  // while addr + size % kShadowCell != 0.
+  uptr size_for_shadow = RoundUp(addr + size, kShadowCell) - addr;
+  DontNeedShadowFor(addr, size_for_shadow);
   ScopedGlobalProcessor sgp;
   SlotLocker locker(thr, true);
-  ctx->metamap.ResetRange(thr->proc(), addr, size, true);
+  uptr size_for_meta = RoundUp(addr + size, kMetaShadowCell) - addr;
+  ctx->metamap.ResetRange(thr->proc(), addr, size_for_meta, true);
 }
 #endif
 
diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl_access.cpp b/compiler-rt/lib/tsan/rtl/tsan_rtl_access.cpp
index e329cee9751e5..369e040e61650 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_rtl_access.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_rtl_access.cpp
@@ -688,8 +688,10 @@ void MemoryAccessRangeT(ThreadState* thr, uptr pc, uptr addr, uptr size) {
     DCHECK(IsShadowMem(shadow_mem));
   }
 
-  RawShadow* shadow_mem_end = MemToEndShadow(addr + size);
-  if (size > 0 && !IsShadowMem(shadow_mem_end - 1)) {
+  uptr size1 =
+      (RoundUpTo(addr + size, kShadowCell) - RoundDownTo(addr, kShadowCell));
+  RawShadow* shadow_mem_end = shadow_mem + size1 / kShadowCell * kShadowCnt;
+  if (!IsShadowMem(shadow_mem_end - 1)) {
     Printf("Bad shadow end addr: %p (%p)\n", shadow_mem_end - 1,
            (void*)(addr + size - 1));
     Printf(

>From c7f240de1c7581724130c3ce27b31659c004ae9a Mon Sep 17 00:00:00 2001
From: Camsyn <camsyn at foxmail.com>
Date: Sat, 21 Jun 2025 20:50:27 +0800
Subject: [PATCH 4/6] add some assertions

---
 compiler-rt/lib/tsan/rtl/tsan_rtl.cpp  | 10 ++++++++++
 compiler-rt/lib/tsan/rtl/tsan_sync.cpp | 14 ++++++++++++++
 2 files changed, 24 insertions(+)

diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp b/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp
index f2b60e7e24cb3..df29f34cd8492 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp
@@ -582,6 +582,16 @@ void UnmapShadow(ThreadState* thr, uptr addr, uptr size) {
 #endif
 
 void MapShadow(uptr addr, uptr size) {
+  // Although named MapShadow, this function's semantic is unrelated to
+  // UnmapShadow. This function currently only used for Go's lazy allocation
+  // of shadow, whose targets are program section (e.g., bss, data, etc.).
+  // Therefore, we can guarantee that the addr and size align to kShadowCell
+  // and kMetaShadowCell by the following assertions.
+  DCHECK_EQ(addr % kShadowCell, 0);
+  DCHECK_EQ(size % kShadowCell, 0);
+  DCHECK_EQ(addr % kMetaShadowCell, 0);
+  DCHECK_EQ(size % kMetaShadowCell, 0);
+
   // Ensure thead registry lock held, so as to synchronize
   // with DoReset, which also access the mapped_shadow_* ctxt fields.
   ThreadRegistryLock lock0(&ctx->thread_registry);
diff --git a/compiler-rt/lib/tsan/rtl/tsan_sync.cpp b/compiler-rt/lib/tsan/rtl/tsan_sync.cpp
index 97335bc8ecf71..be5829bc823dc 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_sync.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_sync.cpp
@@ -246,6 +246,20 @@ void MetaMap::MoveMemory(uptr src, uptr dst, uptr sz) {
   // there are no concurrent accesses to the regions (e.g. stop-the-world).
   CHECK_NE(src, dst);
   CHECK_NE(sz, 0);
+
+  // The current MoveMemory implementation behaves incorrectly when src, dst,
+  // and sz are not aligned to kMetaShadowCell.
+  // For example, with kMetaShadowCell == 8:
+  // - src = 4: unexpectedly clears the metadata for the range [0, 4).
+  // - src = 16, dst = 4, size = 8: A sync variable for addr = 20, which should
+  //   be moved to the metadata for address 8, is incorrectly moved to the
+  //   metadata for address 0 instead.
+  // - src = 0, sz = 4: fails to move the tail metadata.
+  // Therefore, the following assertions is needed.
+  DCHECK_EQ(src % kMetaShadowCell, 0);
+  DCHECK_EQ(dst % kMetaShadowCell, 0);
+  DCHECK_EQ(sz % kMetaShadowCell, 0);
+
   uptr diff = dst - src;
   u32 *src_meta, *dst_meta, *src_meta_end;
   uptr inc;

>From e01c42a6a06acf1a63b7f856613d26e06a863a5c Mon Sep 17 00:00:00 2001
From: Camsyn <camsyn at foxmail.com>
Date: Sat, 21 Jun 2025 21:51:01 +0800
Subject: [PATCH 5/6] Revert "Fix the wrong description."

This reverts commit 4c59a82aa57bb5568c275b9188f12252b7817b51.

Reason: move this unrelated change to another NFC PR.
---
 compiler-rt/lib/sanitizer_common/sanitizer_common.h | 2 +-
 compiler-rt/lib/sanitizer_common/sanitizer_linux.h  | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common.h b/compiler-rt/lib/sanitizer_common/sanitizer_common.h
index 3f52cfcaeecaa..d9e7ded593feb 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common.h
@@ -166,7 +166,7 @@ uptr FindAvailableMemoryRange(uptr size, uptr alignment, uptr left_padding,
 
 // Used to check if we can map shadow memory to a fixed location.
 bool MemoryRangeIsAvailable(uptr range_start, uptr range_end);
-// Releases memory pages entirely within the [beg, end) address range. Noop if
+// Releases memory pages entirely within the [beg, end] address range. Noop if
 // the provided range does not contain at least one entire page.
 void ReleaseMemoryPagesToOS(uptr beg, uptr end);
 void IncreaseTotalMmap(uptr size);
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h
index 05b7d2e28a610..6959f785990f9 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h
@@ -130,7 +130,7 @@ bool LibraryNameIs(const char *full_name, const char *base_name);
 // Call cb for each region mapped by map.
 void ForEachMappedRegion(link_map *map, void (*cb)(const void *, uptr));
 
-// Releases memory pages entirely within the [beg, end) address range.
+// Releases memory pages entirely within the [beg, end] address range.
 // The pages no longer count toward RSS; reads are guaranteed to return 0.
 // Requires (but does not verify!) that pages are MAP_PRIVATE.
 inline void ReleaseMemoryPagesToOSAndZeroFill(uptr beg, uptr end) {

>From b14fac40ed8343bc562e41c9967f1b6885cd3051 Mon Sep 17 00:00:00 2001
From: Camsyn <camsyn at foxmail.com>
Date: Sat, 21 Jun 2025 22:29:42 +0800
Subject: [PATCH 6/6] Remove all MemToEndShadow usages

---
 compiler-rt/lib/tsan/rtl/tsan_rtl.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp b/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp
index df29f34cd8492..9c42c617cb949 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp
@@ -603,12 +603,12 @@ void MapShadow(uptr addr, uptr size) {
   // CHECK_EQ(addr, addr & ~((64 << 10) - 1));  // windows wants 64K alignment
   const uptr kPageSize = GetPageSizeCached();
   uptr shadow_begin = RoundDownTo((uptr)MemToShadow(addr), kPageSize);
-  uptr shadow_end = RoundUpTo((uptr)MemToEndShadow(addr + size), kPageSize);
+  uptr shadow_end = RoundUpTo((uptr)MemToShadow(addr + size), kPageSize);
   if (!MmapFixedNoReserve(shadow_begin, shadow_end - shadow_begin, "shadow"))
     Die();
 #else
   uptr shadow_begin = RoundDownTo((uptr)MemToShadow(addr), (64 << 10));
-  uptr shadow_end = RoundUpTo((uptr)MemToEndShadow(addr + size), (64 << 10));
+  uptr shadow_end = RoundUpTo((uptr)MemToShadow(addr + size), (64 << 10));
   VPrintf(2, "MapShadow for (0x%zx-0x%zx), begin/end: (0x%zx-0x%zx)\n",
           addr, addr + size, shadow_begin, shadow_end);
 



More information about the llvm-commits mailing list