[compiler-rt] [tsan][riscv] add Go race detector support for RISC-V sv39 VMA (PR #154701)

Thurston Dang via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 21 10:42:15 PDT 2025


================
@@ -681,6 +681,33 @@ struct MappingGoMips64_47 {
   static const uptr kShadowAdd = 0x200000000000ull;
 };
 
+/* Go on linux/riscv64 (39-bit VMA)
+0000 0000 0000 - 000a 0000 0000: executable and heap (40 GiB)
+000a 0000 0000 - 000c 0000 0000: -
+000c 0000 0000 - 0034 0000 0000: shadow - 160 GiB ( ~ 4 * app)
+0034 0000 0000 - 0035 0000 0000: -
+0035 0000 0000 - 0039 0000 0000: metainfo - 40 GiB ( ~ 1 * app)
+0039 0000 0000 - 0040 0000 0000: -
+*/
+struct MappingGoRiscv64_39 {
+  static const uptr kMetaShadowBeg = 0x003500000000ull;
+  static const uptr kMetaShadowEnd = 0x003900000000ull;
----------------
thurstond wrote:

`ninja check-tsan` fails:

```
  addr=0x1fe00cd08: shadow=0xffc019a10 meta=0x0035ff006684 reverse=0x1fe00cd08
  addr=0x20800cbf8: shadow=0x10100197f0 meta=0x0035040065fc reverse=0x20800cbf8
ThreadSanitizer: CHECK failed: tsan_shadow_test.cpp:203 "((m - prev_m)) == (((p - prev) / kMetaShadowCell))" (0xffffffffc13fffde, 0x13fffde) (tid=1672899)
```

The reason is the kMetaShadowBeg is applied as a bit-wise OR:
```
struct MemToMetaImpl {
  template <typename Mapping>
  static u32 *Apply(uptr x) {
    DCHECK(IsAppMemImpl::Apply<Mapping>(x));
    return (u32 *)(((((x) & ~(Mapping::kShadowMsk | (kMetaShadowCell - 1)))) /
                    kMetaShadowCell * kMetaShadowSize) |
                   Mapping::kMetaShadowBeg);
  }
};
```
and that means when a meta value is supposed to be in the 0x003600000000 range, it flips back into the 0x003600000000 | 0x003500000000 == 0x003500000000 range.

https://github.com/llvm/llvm-project/pull/154701


More information about the llvm-commits mailing list