Skip to content

Commit ea9ae97

Browse files
committed
[hwasan] Optimize outlined memaccess for fixed shadow on Aarch64
The HWASan transform currently always uses x20 to pass the shadow base to hwasan_check_memaccess_shortgranules, even if the shadow base is a constant known at compile time (via -hwasan-mapping-offset). This patch uses the fixed shadow variant of the hwasan_check_memaccess_shortgranules intrinsic (introduced in 365bddf), allowing the shadow base to be materialized inside the memaccess callee. We currently only support this optimization for AArch64. It is a no-op on other platforms, or if -hwasan-mapping-offset is not specified. Note: when -hwasan-mapping-offset is specified, it is necessary to specify HWASAN_OPTIONS=fixed_shadow_base=... (see ea991a1) to ensure that the runtime will map the shadow appropriately.
1 parent 30d4f6a commit ea9ae97

File tree

1 file changed

+26
-5
lines changed

1 file changed

+26
-5
lines changed

llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -930,11 +930,32 @@ void HWAddressSanitizer::instrumentMemAccessOutline(Value *Ptr, bool IsWrite,
930930

931931
IRBuilder<> IRB(InsertBefore);
932932
Module *M = IRB.GetInsertBlock()->getParent()->getParent();
933-
IRB.CreateCall(Intrinsic::getDeclaration(
934-
M, UseShortGranules
935-
? Intrinsic::hwasan_check_memaccess_shortgranules
936-
: Intrinsic::hwasan_check_memaccess),
937-
{ShadowBase, Ptr, ConstantInt::get(Int32Ty, AccessInfo)});
933+
bool useFixedShadowIntrinsic = false;
934+
// The memaccess fixed shadow intrinsic is only supported on AArch64,
935+
// which allows a 16-bit immediate to be left-shifted by 32.
936+
// Since kShadowBaseAlignment == 32, and Linux by default will not
937+
// mmap above 48-bits, practically any valid shadow offset is
938+
// representable.
939+
// In particular, an offset of 4TB (1024 << 32) is representable, and
940+
// ought to be good enough for anybody.
941+
if (TargetTriple.isAArch64() && ClMappingOffset.getNumOccurrences() > 0) {
942+
uint16_t offset_shifted = Mapping.Offset >> 32;
943+
useFixedShadowIntrinsic = (uint64_t)offset_shifted << 32 == Mapping.Offset;
944+
}
945+
946+
if (useFixedShadowIntrinsic)
947+
IRB.CreateCall(
948+
Intrinsic::getDeclaration(
949+
M, UseShortGranules
950+
? Intrinsic::hwasan_check_memaccess_shortgranules_fixedshadow
951+
: Intrinsic::hwasan_check_memaccess_fixedshadow),
952+
{Ptr, ConstantInt::get(Int32Ty, AccessInfo), ConstantInt::get(Int64Ty, Mapping.Offset)});
953+
else
954+
IRB.CreateCall(Intrinsic::getDeclaration(
955+
M, UseShortGranules
956+
? Intrinsic::hwasan_check_memaccess_shortgranules
957+
: Intrinsic::hwasan_check_memaccess),
958+
{ShadowBase, Ptr, ConstantInt::get(Int32Ty, AccessInfo)});
938959
}
939960

940961
void HWAddressSanitizer::instrumentMemAccessInline(Value *Ptr, bool IsWrite,

0 commit comments

Comments
 (0)