[llvm] 314c049 - [compiler-rt][hwasan] Decouple use of the TLS global for getting the shadow base and using the frame record feature
Leonard Chan via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 9 12:55:40 PDT 2021
Author: Leonard Chan
Date: 2021-06-09T12:55:19-07:00
New Revision: 314c049142ed22154fbe37de3a566ef38b884fab
URL: https://github.com/llvm/llvm-project/commit/314c049142ed22154fbe37de3a566ef38b884fab
DIFF: https://github.com/llvm/llvm-project/commit/314c049142ed22154fbe37de3a566ef38b884fab.diff
LOG: [compiler-rt][hwasan] Decouple use of the TLS global for getting the shadow base and using the frame record feature
This allows for using the frame record feature (which uses __hwasan_tls)
independently from however the user wants to access the shadow base, which
prior was only usable if shadow wasn't accessed through the TLS variable or ifuncs.
Frame recording can be explicitly set according to ShadowMapping::WithFrameRecord
in ShadowMapping::init. Currently, it is only enabled on Fuchsia and if TLS is
used, so this should mimic the old behavior.
Added an extra case to prologue.ll that covers this new case.
Differential Revision: https://reviews.llvm.org/D103841
Added:
Modified:
llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
llvm/test/Instrumentation/HWAddressSanitizer/prologue.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
index 3d6b12489a8d2..9b02410f09075 100644
--- a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
@@ -264,11 +264,15 @@ class HWAddressSanitizer {
/// If InTls is true, then
/// extern char *__hwasan_tls;
/// shadow = (mem>>Scale) + align_up(__hwasan_shadow, kShadowBaseAlignment)
+ ///
+ /// If WithFrameRecord is true, then __hwasan_tls will be used to access the
+ /// ring buffer for storing stack allocations on targets that support it.
struct ShadowMapping {
int Scale;
uint64_t Offset;
bool InGlobal;
bool InTls;
+ bool WithFrameRecord;
void init(Triple &TargetTriple, bool InstrumentWithCalls);
unsigned getObjectAlignment() const { return 1U << Scale; }
@@ -1042,15 +1046,13 @@ Value *HWAddressSanitizer::getHwasanThreadSlotPtr(IRBuilder<> &IRB, Type *Ty) {
}
void HWAddressSanitizer::emitPrologue(IRBuilder<> &IRB, bool WithFrameRecord) {
- if (!Mapping.InTls) {
+ if (!Mapping.InTls)
ShadowBase = getShadowNonTls(IRB);
- return;
- }
-
- if (!WithFrameRecord && TargetTriple.isAndroid()) {
+ else if (!WithFrameRecord && TargetTriple.isAndroid())
ShadowBase = getDynamicShadowIfunc(IRB);
+
+ if (!WithFrameRecord && ShadowBase)
return;
- }
Value *SlotPtr = getHwasanThreadSlotPtr(IRB, IntptrTy);
assert(SlotPtr);
@@ -1106,15 +1108,17 @@ void HWAddressSanitizer::emitPrologue(IRBuilder<> &IRB, bool WithFrameRecord) {
IRB.CreateStore(ThreadLongNew, SlotPtr);
}
- // Get shadow base address by aligning RecordPtr up.
- // Note: this is not correct if the pointer is already aligned.
- // Runtime library will make sure this never happens.
- ShadowBase = IRB.CreateAdd(
- IRB.CreateOr(
- ThreadLongMaybeUntagged,
- ConstantInt::get(IntptrTy, (1ULL << kShadowBaseAlignment) - 1)),
- ConstantInt::get(IntptrTy, 1), "hwasan.shadow");
- ShadowBase = IRB.CreateIntToPtr(ShadowBase, Int8PtrTy);
+ if (!ShadowBase) {
+ // Get shadow base address by aligning RecordPtr up.
+ // Note: this is not correct if the pointer is already aligned.
+ // Runtime library will make sure this never happens.
+ ShadowBase = IRB.CreateAdd(
+ IRB.CreateOr(
+ ThreadLongMaybeUntagged,
+ ConstantInt::get(IntptrTy, (1ULL << kShadowBaseAlignment) - 1)),
+ ConstantInt::get(IntptrTy, 1), "hwasan.shadow");
+ ShadowBase = IRB.CreateIntToPtr(ShadowBase, Int8PtrTy);
+ }
}
Value *HWAddressSanitizer::readRegister(IRBuilder<> &IRB, StringRef Name) {
@@ -1273,7 +1277,7 @@ bool HWAddressSanitizer::sanitizeFunction(Function &F) {
IRBuilder<> EntryIRB(InsertPt);
emitPrologue(EntryIRB,
/*WithFrameRecord*/ ClRecordStackHistory &&
- !AllocasToInstrument.empty());
+ Mapping.WithFrameRecord && !AllocasToInstrument.empty());
if (!AllocasToInstrument.empty()) {
Value *StackTag =
@@ -1540,25 +1544,31 @@ void HWAddressSanitizer::ShadowMapping::init(Triple &TargetTriple,
InGlobal = false;
InTls = false;
Offset = 0;
+ WithFrameRecord = true;
} else if (ClMappingOffset.getNumOccurrences() > 0) {
InGlobal = false;
InTls = false;
Offset = ClMappingOffset;
+ WithFrameRecord = false;
} else if (ClEnableKhwasan || InstrumentWithCalls) {
InGlobal = false;
InTls = false;
Offset = 0;
+ WithFrameRecord = false;
} else if (ClWithIfunc) {
InGlobal = true;
InTls = false;
Offset = kDynamicShadowSentinel;
+ WithFrameRecord = false;
} else if (ClWithTls) {
InGlobal = false;
InTls = true;
Offset = kDynamicShadowSentinel;
+ WithFrameRecord = true;
} else {
InGlobal = false;
InTls = false;
Offset = kDynamicShadowSentinel;
+ WithFrameRecord = false;
}
}
diff --git a/llvm/test/Instrumentation/HWAddressSanitizer/prologue.ll b/llvm/test/Instrumentation/HWAddressSanitizer/prologue.ll
index d74940fe68a28..4a03922269039 100644
--- a/llvm/test/Instrumentation/HWAddressSanitizer/prologue.ll
+++ b/llvm/test/Instrumentation/HWAddressSanitizer/prologue.ll
@@ -1,15 +1,17 @@
; Test -hwasan-with-ifunc flag.
;
; RUN: opt -hwasan -S < %s | \
-; RUN: FileCheck %s --check-prefixes=CHECK,CHECK-NOGLOBAL,CHECK-TLS,CHECK-HISTORY
+; RUN: FileCheck %s --check-prefixes=CHECK,CHECK-NOGLOBAL,CHECK-TLS-SLOT,CHECK-HISTORY,CHECK-HISTORY-TLS-SLOT
; RUN: opt -hwasan -S -hwasan-with-ifunc=0 -hwasan-with-tls=1 -hwasan-record-stack-history=1 < %s | \
-; RUN: FileCheck %s --check-prefixes=CHECK,CHECK-NOGLOBAL,CHECK-TLS,CHECK-HISTORY
+; RUN: FileCheck %s --check-prefixes=CHECK,CHECK-NOGLOBAL,CHECK-TLS-SLOT,CHECK-HISTORY,CHECK-HISTORY-TLS-SLOT
; RUN: opt -hwasan -S -hwasan-with-ifunc=0 -hwasan-with-tls=1 -hwasan-record-stack-history=0 < %s | \
; RUN: FileCheck %s --check-prefixes=CHECK,CHECK-NOGLOBAL,CHECK-IFUNC,CHECK-NOHISTORY
; RUN: opt -hwasan -S -hwasan-with-ifunc=0 -hwasan-with-tls=0 < %s | \
; RUN: FileCheck %s --check-prefixes=CHECK,CHECK-GLOBAL,CHECK-NOHISTORY
; RUN: opt -hwasan -S -hwasan-with-ifunc=1 -hwasan-with-tls=0 < %s | \
; RUN: FileCheck %s --check-prefixes=CHECK,CHECK-IFUNC,CHECK-NOHISTORY
+; RUN: opt -hwasan -S -mtriple=aarch64-fuchsia < %s | \
+; RUN: FileCheck %s --check-prefixes=CHECK,CHECK-ZERO-OFFSET,CHECK-SHORT-GRANULES,CHECK-HISTORY,CHECK-HWASAN-TLS,CHECK-HISTORY-HWASAN-TLS
target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
target triple = "aarch64--linux-android22"
@@ -25,6 +27,8 @@ define i32 @test_load(i32* %a) sanitize_hwaddress {
; CHECK-NOGLOBAL: %[[A:[^ ]*]] = call i8* asm "", "=r,0"([0 x i8]* @__hwasan_shadow)
; CHECK-NOGLOBAL: @llvm.hwasan.check.memaccess(i8* %[[A]]
+; CHECK-ZERO-OFFSET: %[[A:[^ ]*]] = call i8* asm "", "=r,0"(i8* null)
+; CHECK-SHORT-GRANULES: @llvm.hwasan.check.memaccess.shortgranules(i8* %[[A]]
; CHECK-GLOBAL: load i8*, i8** @__hwasan_shadow_memory_dynamic_address
@@ -52,11 +56,13 @@ define void @test_alloca() sanitize_hwaddress {
; CHECK-GLOBAL: load i8*, i8** @__hwasan_shadow_memory_dynamic_address
-; CHECK-TLS: %[[A:[^ ]*]] = call i8* @llvm.thread.pointer()
-; CHECK-TLS: %[[B:[^ ]*]] = getelementptr i8, i8* %[[A]], i32 48
-; CHECK-TLS: %[[C:[^ ]*]] = bitcast i8* %[[B]] to i64*
-; CHECK-TLS: %[[D:[^ ]*]] = load i64, i64* %[[C]]
-; CHECK-TLS: %[[E:[^ ]*]] = ashr i64 %[[D]], 3
+; CHECK-TLS-SLOT: %[[A:[^ ]*]] = call i8* @llvm.thread.pointer()
+; CHECK-TLS-SLOT: %[[B:[^ ]*]] = getelementptr i8, i8* %[[A]], i32 48
+; CHECK-TLS-SLOT: %[[C:[^ ]*]] = bitcast i8* %[[B]] to i64*
+; CHECK-TLS-SLOT: %[[D:[^ ]*]] = load i64, i64* %[[C]]
+; CHECK-TLS-SLOT: %[[E:[^ ]*]] = ashr i64 %[[D]], 3
+; CHECK-HWASAN-TLS: %[[D:[^ ]*]] = load i64, i64* @__hwasan_tls, align 8
+; CHECK-HWASAN-TLS: %[[E:[^ ]*]] = ashr i64 %[[D]], 3
; CHECK-NOHISTORY-NOT: store i64
@@ -68,7 +74,8 @@ define void @test_alloca() sanitize_hwaddress {
; CHECK-HISTORY: %[[D3:[^ ]*]] = xor i64 %[[D2]], -1
; CHECK-HISTORY: %[[D4:[^ ]*]] = add i64 %[[D]], 8
; CHECK-HISTORY: %[[D5:[^ ]*]] = and i64 %[[D4]], %[[D3]]
-; CHECK-HISTORY: store i64 %[[D5]], i64* %[[C]]
+; CHECK-HISTORY-TLS-SLOT: store i64 %[[D5]], i64* %[[C]]
+; CHECK-HISTORY-HWASAN-TLS: store i64 %[[D5]], i64* @__hwasan_tls
; CHECK-TLS: %[[F:[^ ]*]] = or i64 %[[D]], 4294967295
; CHECK-TLS: = add i64 %[[F]], 1
More information about the llvm-commits
mailing list