mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-01 13:11:39 +01:00
[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
This commit is contained in:
parent
c35099a5e4
commit
fca9191cc7
@ -264,11 +264,15 @@ private:
|
||||
/// 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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user