[compiler-rt] 20edc84 - [compiler-rt][TySan] Use pointer-width types for shadow memory ops (#191602)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 14 07:11:53 PDT 2026
Author: Brian Cain
Date: 2026-04-14T09:11:47-05:00
New Revision: 20edc8496df3b2e5fc08df89c6ca7b77f5e2aaf8
URL: https://github.com/llvm/llvm-project/commit/20edc8496df3b2e5fc08df89c6ca7b77f5e2aaf8
DIFF: https://github.com/llvm/llvm-project/commit/20edc8496df3b2e5fc08df89c6ca7b77f5e2aaf8.diff
LOG: [compiler-rt][TySan] Use pointer-width types for shadow memory ops (#191602)
The TySan runtime used uint64_t/int64_t casts for shadow memory pointer
arithmetic and interior-byte marker values. These are incorrect on
32-bit targets where pointers are 4 bytes: the shadow entries are
pointer-sized, so the offsets and marker values must also be
pointer-sized.
Replace uint64_t/int64_t with uptr/sptr (sanitizer_common's
pointer-width typedefs) throughout SetShadowType, GetNotAllBadTD,
GetNotAllUnkTD, and __tysan_instrument_mem_inst. This is a no-op on
64-bit targets (where uptr == uint64_t) and fixes shadow corruption on
32-bit targets.
Added:
Modified:
compiler-rt/lib/tysan/tysan.cpp
Removed:
################################################################################
diff --git a/compiler-rt/lib/tysan/tysan.cpp b/compiler-rt/lib/tysan/tysan.cpp
index 52f941180b8eb..7c1cf193d3cb6 100644
--- a/compiler-rt/lib/tysan/tysan.cpp
+++ b/compiler-rt/lib/tysan/tysan.cpp
@@ -265,33 +265,33 @@ static void SetShadowType(tysan_type_descriptor *td,
tysan_type_descriptor **shadowData,
uint64_t AccessSize) {
*shadowData = td;
- uint64_t shadowDataInt = (uint64_t)shadowData;
+ uptr shadowDataInt = (uptr)shadowData;
for (uint64_t i = 1; i < AccessSize; ++i) {
- int64_t dataOffset = i << PtrShift();
- int64_t *badShadowData = (int64_t *)(shadowDataInt + dataOffset);
- int64_t badTD = int64_t(i) * -1;
+ uptr dataOffset = i << PtrShift();
+ sptr *badShadowData = (sptr *)(shadowDataInt + dataOffset);
+ sptr badTD = sptr(i) * -1;
*badShadowData = badTD;
}
}
ALWAYS_INLINE
-static bool GetNotAllBadTD(uint64_t ShadowDataInt, uint64_t AccessSize) {
+static bool GetNotAllBadTD(uptr ShadowDataInt, uint64_t AccessSize) {
bool notAllBadTD = false;
for (uint64_t i = 1; i < AccessSize; ++i) {
- int64_t **unkShadowData = (int64_t **)(ShadowDataInt + (i << PtrShift()));
- int64_t *ILdTD = *unkShadowData;
+ sptr **unkShadowData = (sptr **)(ShadowDataInt + (i << PtrShift()));
+ sptr *ILdTD = *unkShadowData;
notAllBadTD = notAllBadTD || (ILdTD != nullptr);
}
return notAllBadTD;
}
ALWAYS_INLINE
-static bool GetNotAllUnkTD(uint64_t ShadowDataInt, uint64_t AccessSize) {
+static bool GetNotAllUnkTD(uptr ShadowDataInt, uint64_t AccessSize) {
bool notAllBadTD = false;
for (uint64_t i = 1; i < AccessSize; ++i) {
- int64_t *badShadowData = (int64_t *)(ShadowDataInt + (i << PtrShift()));
- int64_t ILdTD = *badShadowData;
+ sptr *badShadowData = (sptr *)(ShadowDataInt + (i << PtrShift()));
+ sptr ILdTD = *badShadowData;
notAllBadTD = notAllBadTD || (ILdTD >= 0);
}
return notAllBadTD;
@@ -307,9 +307,8 @@ __tysan_instrument_mem_inst(char *dest, char *src, uint64_t size,
return;
}
- uint64_t srcInt = (uint64_t)src;
- uint64_t srcShadowInt = ((srcInt & AppMask()) << PtrShift()) + ShadowAddr();
- uint64_t *srcShadow = (uint64_t *)srcShadowInt;
+ uptr srcShadowInt = ((((uptr)src) & AppMask()) << PtrShift()) + ShadowAddr();
+ void *srcShadow = (void *)srcShadowInt;
if (needsMemMove) {
internal_memmove((char *)destShadowDataPtr, srcShadow, size << PtrShift());
@@ -389,7 +388,7 @@ __tysan_instrument_with_shadow_update(void *ptr, tysan_type_descriptor *td,
if (shadowIsNull) {
// We're about to set the type. Make sure that all bytes in the value
// are also of unknown type.
- bool isAllUnknownTD = GetNotAllUnkTD((uint64_t)shadowData, accessSize);
+ bool isAllUnknownTD = GetNotAllUnkTD((uptr)shadowData, accessSize);
if (isAllUnknownTD) {
GET_CALLER_PC_BP_SP;
__tysan_check_internal(ptr, accessSize, td, flags, pc, bp, sp);
@@ -402,7 +401,7 @@ __tysan_instrument_with_shadow_update(void *ptr, tysan_type_descriptor *td,
} else {
// We appear to have the right type. Make sure that all other bytes in
// the type are still marked as interior bytes. If not, call the runtime.
- bool isNotAllBadTD = GetNotAllBadTD((uint64_t)shadowData, accessSize);
+ bool isNotAllBadTD = GetNotAllBadTD((uptr)shadowData, accessSize);
if (isNotAllBadTD) {
GET_CALLER_PC_BP_SP;
__tysan_check_internal(ptr, accessSize, td, flags, pc, bp, sp);
More information about the llvm-commits
mailing list